Linux RabbitMQ 单机安装与集群搭建(服务器架设篇)

RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。AMQP(Advanced Message Queue),高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。

RabbitMQ 最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。具体特点包括:

  • 可靠性(Reliability)

    RabbitMQ 使用一些机制来保证可靠性,如持久化、传输确认、发布确认。

  • 灵活的路由(Flexible Routing)

    在消息进入队列之前,通过 Exchange 来路由消息的。对于典型的路由功能,RabbitMQ 已经提供了一些内置的 Exchange 来实现。针对更复杂的路由功能,可以将多个 Exchange 绑定在一起,也通过插件机制实现自己的 Exchange 。

  • 消息集群(Clustering)

    多个 RabbitMQ 服务器可以组成一个集群,形成一个逻辑 Broker 。

  • 高可用(Highly Available Queues)

    队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用。

  • 多种协议(Multi-protocol)

    RabbitMQ 支持多种消息队列协议,比如 STOMP、MQTT 等等。

  • 多语言客户端(Many Clients)

    RabbitMQ 几乎支持所有常用语言,比如 Java、.NET、Ruby 等等。

  • 管理界面(Management UI)

    RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方面。

  • 跟踪机制(Tracing)

    如果消息异常,RabbitMQ 提供了消息跟踪机制,使用者可以找出发生了什么。

  • 插件机制(Plugin System)

    RabbitMQ 提供了许多插件,来从多方面进行扩展,也可以编写自己的插件。

本文主要是介绍RabbitMQ的安装

单机安装

根据RabbitMQ的官方网站说明,RabbitMQ是需要有Erlang环境的,RabbitMQ 3.7.8至少是Erlang 19.3.6.4以上。

环境 版本
RHEL/CentOS 7.x
Erlang 21.1.x
RabbitMQ 3.7.x

我们先下载并安装Erlang,我们直接安装最新的Erlang RPM包,版本为21.1.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@localhost thinktik]# ls
apache-activemq-5.15.7 httpd-2.4.37 maven
apache-activemq-5.15.7-bin.tar.gz httpd-2.4.37.tar.gz sonarqube-6.7.5
apache-maven-3.6.0-bin.tar.gz java8 sonarqube-6.7.5.tar
erlang-21.1.1-1.el7.centos.x86_64.rpm jdk-8u191-linux-x64.tar.gz zookeeper-3.4.13
httpd jenkins.war zookeeper-3.4.13.tar.gz
[root@localhost thinktik]# yum install erlang-21.1.1-1.el7.centos.x86_64.rpm
Loaded plugins: fastestmirror
Examining erlang-21.1.1-1.el7.centos.x86_64.rpm: erlang-21.1.1-1.el7.centos.x86_64
Marking erlang-21.1.1-1.el7.centos.x86_64.rpm to be installed
Resolving Dependencies

...

Total size: 31 M
Installed size: 31 M
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : erlang-21.1.1-1.el7.centos.x86_64 1/1
Verifying : erlang-21.1.1-1.el7.centos.x86_64 1/1

Installed:
erlang.x86_64 0:21.1.1-1.el7.centos

Complete!

RabbitMQ的依赖环境满足了,接着进行下一步

这里Linux有两种安装方式:

  1. 具体平台的预发布包安装(RabbitMQ官方推荐这种)
  2. Linux通用的二进制包(这样灵活度更好)

我先介绍最简单的第一种:

参考这个官方的安装文档,先下载RPM格式的RabbitMQ安装包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[root@localhost thinktik]# ls
apache-activemq-5.15.7 httpd-2.4.37.tar.gz sonarqube-6.7.5
apache-activemq-5.15.7-bin.tar.gz java8 sonarqube-6.7.5.tar
apache-maven-3.6.0-bin.tar.gz jdk-8u191-linux-x64.tar.gz zookeeper-3.4.13
erlang-21.1.1-1.el7.centos.x86_64.rpm jenkins.war zookeeper-3.4.13.tar.gz
httpd maven
httpd-2.4.37 rabbitmq-server-3.7.8-1.el7.noarch.rpm
[root@localhost thinktik]# yum install rabbitmq-server-3.7.8-1.el7.noarch.rpm
Loaded plugins: fastestmirror
Examining rabbitmq-server-3.7.8-1.el7.noarch.rpm: rabbitmq-server-3.7.8-1.el7.noarch
Marking rabbitmq-server-3.7.8-1.el7.noarch.rpm to be installed
Resolving Dependencies

...

Dependency Installed:
socat.x86_64 0:1.7.3.2-2.el7

Complete!

# 安装完成

# 启动服务
[root@localhost ~]# systemctl start rabbitmq-server
# 设为开机自启动
[root@localhost ~]# systemctl enable rabbitmq-server
Created symlink from /etc/systemd/system/multi-user.target.wants/rabbitmq-server.service to /usr/lib/systemd/system/rabbitmq-server.service.
# 检查状态
[root@localhost ~]# systemctl status rabbitmq-server
● rabbitmq-server.service - RabbitMQ broker
Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; enabled; vendor preset: disabled)
Active: active (running) since Sun 2018-11-11 20:07:48 CST; 17s ago
Main PID: 18653 (beam.smp)
Status: "Initialized"
CGroup: /system.slice/rabbitmq-server.service
├─18653 /usr/lib64/erlang/erts-9.3.3.3/bin/beam.smp -W w -A 64 -MBas ageffcbf -MHas ageffcbf ...
├─18810 /usr/lib64/erlang/erts-9.3.3.3/bin/epmd -daemon
├─18971 erl_child_setup 32768
├─18985 inet_gethost 4
└─18986 inet_gethost 4

...

Hint: Some lines were ellipsized, use -l to show in full.

这里RabbitMQ的单机版基本就是安装完成了

我们看下RabbitMQ的后台管理界面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost ~]# rabbitmq-plugins enable rabbitmq_management
The following plugins have been configured:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch
Applying plugin configuration to rabbit@localhost...
The following plugins have been enabled:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch

started 3 plugins.

# 防火墙放行后台管理端口
[root@localhost ~]# firewall-cmd --zone=public --add-port=15672/tcp --permanent
success
[root@localhost ~]# firewall-cmd --reload
success

浏览器访问http://ip:15672/,输入用户名和密码(默认都为guest)

我这里不是localhost或者128.0.0.1本机登陆所以没登陆上,这是安全的考虑,不是程序安装的错误,你可以自己再继续配置安全策略解决这个问题。

安装最新版本的rabbitmq并启用management plugin后,使用默认的账号guest登陆管理控制台,却提示登陆失败。翻看官方的release文档后,得知由于账号guest具有所有的操作权限,并且又是默认账号,出于安全因素的考虑,guest用户只能通过localhost登陆使用,并建议修改guest用户的密码以及新建其他账号管理使用rabbitmq(该功能是在3.3.0版本引入的)。

目前很多我们开发常用的软件都提供主流Linux发行版的二进制安装包,这方式证明的确是很简单方便的,也推荐大家多使用这种方式,处理安装简单这种方式后续的安全补丁和升级也方便很多。如果你希望还是采用Linux通用的二进制包安装来获得更高的灵活性,那么可以继续向下看,这种方式不需要root权限而且可以安在你自己想要的任何文件下,灵活性很好。

我们下载linux通用的二进制包

安装参考官方的安装文档

先安装Erlang我就不讲了,直接讲Linux通用包安装Linux

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
[root@localhost thinktik]# ls
erlang-20.3.8.7-1.el7.centos.x86_64.rpm rabbitmq-server-generic-unix-3.7.8.tar.xz
java8 zookeeper
jdk-8u191-linux-x64.tar.gz zookeeper-3.4.13.tar.gz
# 解压
[root@localhost thinktik]# tar -zxvf rabbitmq-server-generic-unix-3.7.8.tar.xz

[root@localhost thinktik]# ls
erlang-20.3.8.7-1.el7.centos.x86_64.rpm rabbitmq-server-generic-unix-3.7.8.tar.xz
java8 zookeeper
jdk-8u191-linux-x64.tar.gz zookeeper-3.4.13.tar.gz
rabbitmq_server-3.7.8
[root@localhost thinktik]# cd rabbitmq_server-3.7.8/
[root@localhost rabbitmq_server-3.7.8]# ls
ebin LICENSE-APACHE2-excanvas LICENSE-ISC-cowboy LICENSE-MIT-Mochi priv
escript LICENSE-APACHE2-ExplorerCanvas LICENSE-MIT-EJS LICENSE-MIT-Sammy sbin
etc LICENSE-APL2-Stomp-Websocket LICENSE-MIT-EJS10 LICENSE-MIT-Sammy060 share
include LICENSE-BSD-base64js LICENSE-MIT-Erlware-Commons LICENSE-MPL2
INSTALL LICENSE-BSD-recon LICENSE-MIT-Flot LICENSE-MPL-RabbitMQ
LICENSE LICENSE-erlcloud LICENSE-MIT-jQuery LICENSE-rabbitmq_aws
LICENSE-APACHE2 LICENSE-httpc_aws LICENSE-MIT-jQuery164 plugins
[root@localhost rabbitmq_server-3.7.8]# cd sbin/
[root@localhost sbin]# ls
cuttlefish rabbitmq-defaults rabbitmq-env rabbitmq-server
rabbitmqctl rabbitmq-diagnostics rabbitmq-plugins

# 启动RabbitMQ
[root@localhost sbin]# ./rabbitmq-server

## ##
## ## RabbitMQ 3.7.8. Copyright (C) 2007-2018 Pivotal Software, Inc.
########## Licensed under the MPL. See http://www.rabbitmq.com/
###### ##
########## Logs: /home/thinktik/rabbitmq_server-3.7.8/var/log/rabbitmq/rabbit@localhost.log
/home/thinktik/rabbitmq_server-3.7.8/var/log/rabbitmq/rabbit@localhost_upgrade.log

Starting broker...
completed with 0 plugins.


# 这样一个RabbitMQ就启动了但是命令行窗口没法关闭,关闭了服务就停了
# 那就这样后台启动
[root@localhost sbin]# ./rabbitmq-server -detached
Warning: PID file not written; -detached was passed.
# 查看状态 运行中
[root@localhost sbin]# ./rabbitmqctl status
Status of node rabbit@localhost ...
[{pid,1429},
{running_applications,

...

# 关闭RabbitMQ
[root@localhost sbin]# ./rabbitmqctl shutdown
Shutting down RabbitMQ node rabbit@localhost running at PID 1429
Waiting for PID 1429 to terminate
RabbitMQ node rabbit@localhost running at PID 1429 successfully shut down

# 我们看下后台启动和普通启动的区别
# 普通启动
[root@localhost sbin]# ./rabbitmq-server

## ##
## ## RabbitMQ 3.7.8. Copyright (C) 2007-2018 Pivotal Software, Inc.
########## Licensed under the MPL. See http://www.rabbitmq.com/
###### ##
########## Logs: /home/thinktik/rabbitmq_server-3.7.8/var/log/rabbitmq/rabbit@localhost.log
/home/thinktik/rabbitmq_server-3.7.8/var/log/rabbitmq/rabbit@localhost_upgrade.log

Starting broker...
completed with 0 plugins.
^Z
Stopping and halting node rabbit@localhost ...
Gracefully halting Erlang VM

# 显然普通启动是没法关闭命令行窗口,所以除非在调试RabbitMQ外还是后台启动好些
[root@localhost sbin]# ./rabbitmqctl status
Status of node rabbit@localhost ...
Error: unable to perform an operation on node 'rabbit@localhost'. Please see diagnostics information and suggestions below.

Most common reasons for this are:


[root@localhost sbin]# ./rabbitmq-plugins enable rabbitmq_management
The following plugins have been configured:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch
Applying plugin configuration to rabbit@localhost...
The following plugins have been enabled:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch

[root@localhost sbin]# netstat -nlp|grep 15672
tcp 0 0 0.0.0.0:15672 0.0.0.0:* LISTEN 4908/beam.smp
[root@localhost sbin]# firewall-cmd --zone=public --add-port=15672/tcp --permanent
success
[root@localhost sbin]# firewall-cmd --reload
success

# 仿照前面的方式用浏览器访问后台管理界面也是可以的,这证明两种方式都差不多,不过这种方式有点不好就是没有将rabbitmq写出一个linux的服务,没法开机自启等便捷操作,不过你可以自己仿照第一种安装方式中rabbitmq的官方服务脚本上的写法抄一个过来

RabbitMQ分布式方案

再搭建前的我先介绍下RabbitMQ的三种分布式方案。根据RabitMQ 官方文档 分布式方案有3种,它们分别是Clustering,Federation,Shovel。

Clustering
Clustering也就是大家通常讲的集群,集群将部署在多台机器上的多个RabbitMQ节点连接在一起组成一个逻辑的中间服务器(Broker). 这些节点之间通过Erlang的消息转递通信,所以所有的节点一定要使用相同的Erlang cookie,同时节点间的网络连接一定要可靠。同时这些节点一定要运行相同版本的RabbitMQ和Erlang.

Virtual hosts(虚拟主机), exchanges(交换机), users(用户信息)和permissions(权限)会自动镜像到集群中各个节点,也就是上面这些信息会在各个节点间同步,这些节点组成了镜像节点。Queues(队列)也许会存在一个节点上也许会镜像到多个节点上,所以对于Queues,各个节点不是一定镜像的,不过一个客户端可以连接到任何节点并看到整个集群全部的队列,即使有些队列在这个客户端连接的节点上不存在。

一般的你可以使用Clustering实现高可用并提升MQ系统的吞吐量,当这些节点处于同样的一个地域(可靠的局域网)间。

Federation

Federation(联盟)允许单台服务器上的交换机或队列接收发布到另一台逻辑上的服务器(可以是单独机器或集群)上交换机或队列的消息。服务器之间通过AMQP协议通信,因此为了两个交换机或队列要组成联盟一定要求设置相应的用户权限

联盟交换机之间由单向点对点链接关联,默认消息只会由联盟链接转发一次,但允许有更复杂的路由拓扑来提高转发次数。消息也可以不进行转发;如果消息到达联盟交换机之后不会路由到队列,那么它再也不会被转发。

联盟队列类似于单向点对点连接,消息会在联盟队列之间转发任意次,直到被消费者接受。

通常使用联盟来连接internet(不太可靠的广域网络环境)上的中间服务器,用作订阅分发消息或工作队列。

Shovel

shovel连接方式与联盟的连接方式在概念上类似,但它工作在更低层次。

相比联盟旨在提供一个队列和交换机的稳定的分布式方案,shovel仅仅是从队列或者交换机上消费消息以及传递消息到例外一个节点的交换机上。

一般的你应该使用shovel来连接internet(不太可靠的广域网络环境)上的中间服务器,当你需要拥有Federation方案所能提供的更多控制权限时。

Federation / Shovel Clustering
中间服务器们(brokers)逻辑独立并且可以有不同的拥有者(user) 一个集群的中间服务器们(brokers)共同组成逻辑上的一个中间服务器
可以使用不同的RabbitMQ和Erlang版本 RabbitMQ和Erlang版本要统一
中间服务器们(brokers)可以在不太可靠的广域网上连接,通过AMQP协议(可选SSL加密)来交换数据,要求合适的用户和权限 中间服务器们(brokers)可以在可靠的局域网上连接,通过Erlang的消息传递来通信,需要共享Erlang Cookie
中间服务器们(brokers)可以通过任何网络拓扑结构连接在一起,连接也有是单向也可以是双向 中间服务器们(brokers)每个互相连接彼此并且都是双向连接
CAP定理中满足AP,侧重在高可用 CAP定理中满足CP,侧重在一致性
一些交换机(exchange)在某一个中间服务器上可能会与其他中间服务器组成联盟(federated) ,也有一些一些交换机(exchange)就只是本地Broker上有 交换机(exchange)在集群间所有的中间服务器要么都存在要么都不存在
一个客户端连接任意一个中间服务器Broker,这个客户端只能看到它所连接的中间服务器上的队列 一个客户端来连接任意一个中间服务器都可以看到集群里面的所有中间服务器的队列,也就是客户端可以全部看到

总结:Clustering 适合单机房里面多台机器间组成分布式MQ,它满足一致性要求,是我们常用的分布式方案。而例外两种适合跨机房间网络环境复杂的环境(通信时间延迟较高,可靠性较差),满足高可用要求而对一致性不保证,这个场景一般我们用的少。

分析完这三种后,我单就Clustering来做进一步的分析(例外两种的确一般人接触的场景不是太多)。

RabbitMQ 的 Cluster 集群模式

RabbitMQ 的 Cluster 集群模式一般分为两种,普通模式和镜像模式。

普通模式:默认的集群模式,以两个节点(rabbit01、rabbit02)为例来进行说明。对于 Queue 来说,消息实体只存在于其中一个节点 rabbit01(或者 rabbit02),rabbit01 和 rabbit02 两个节点仅有相同的元数据,即队列的结构。当消息进入 rabbit01 节点的 Queue 后,consumer 从 rabbit02 节点消费时,RabbitMQ 会临时在 rabbit01、rabbit02 间进行消息传输,把 rabbit01 中的消息实体取出并经过 rabbit02 发送给 consumer。所以 consumer 应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理 Queue。否则无论 consumer 连 rabbit01 或 rabbit02,出口总在 rabbit01,会产生瓶颈。当 rabbit01 节点故障后,rabbit02 节点无法取到 rabbit01 节点中还未消费的消息实体。如果做了消息持久化,那么得等 rabbit01 节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。

镜像模式:将需要消费的队列变为镜像队列,存在于多个节点,这样就可以实现 RabbitMQ 的 HA 高可用性。作用就是消息实体会主动在镜像节点之间实现同步,而不是像普通模式那样,在 consumer 消费数据时临时读取。缺点就是,集群内部的同步通讯会占用大量的网络带宽。

单机安装完成后,依样画葫芦再安装多个RabbitMQ到多个主机上,当然一个主机安装多个RabbitMQ也可以不过除了略微繁琐外也不适合生产环境的分布式系统要求只能用于测试和功能演示。

我这里先安装3个RabbitMQ,具体结构如表:

主机编号 系统 ip
rbmq01 RHEL/CentOS 7.x 192.168.50.38
rbmq02 RHEL/CentOS 7.x 192.168.50.74
rbmq03 RHEL/CentOS 7.x 192.168.50.226

RabbitMQ组件普通模式并不复杂,记住这3个点就可以了:

  1. 节点名唯一,节点名是 rabbit@hostname。那么我们几台主机的主机名唯一就可以了,如果不唯一请修改自己的主机名
  2. 主机之间可以互相解析IP,并且互相开放RabbitMQ需要的端口
  3. Erlang cookie共享

为了达到这三点我逐步演示

rbmq01(192.168.50.38)上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#修改hostname为rbmq01
[root@rbmq01 thinktik]# hostnamectl set-hostname rbmq01
#修改hosts 保证三台主机可以互相ping通
[root@rbmq01 thinktik]# vi /etc/hosts
[root@rbmq01 thinktik]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

rbmq01 192.168.50.38
rbmq02 192.168.50.74
rbmq03 192.168.50.226

# ping 测试
[root@rbmq01 thinktik]# ping rbmq02
PING rbmq02 (192.168.50.74) 56(84) bytes of data.
64 bytes from rbmq02 (192.168.50.74): icmp_seq=1 ttl=64 time=0.678 ms
64 bytes from rbmq02 (192.168.50.74): icmp_seq=2 ttl=64 time=0.627 ms
^C
--- rbmq02 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.627/0.652/0.678/0.036 ms
[root@rbmq01 thinktik]# ping rbmq03
PING rbmq03 (192.168.50.226) 56(84) bytes of data.
64 bytes from rbmq03 (192.168.50.226): icmp_seq=1 ttl=64 time=0.296 ms
64 bytes from rbmq03 (192.168.50.226): icmp_seq=2 ttl=64 time=0.659 ms
^C
--- rbmq03 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.296/0.477/0.659/0.182 ms

其余的两个主机也按照这样操作,那么网络问题解决了,也就1,2条件满足

1
2
3
4
5
6
7
8
# rbmq01上找到Erlang cookie
[root@rbmq01 thinktik]# cat /var/lib/rabbitmq/.erlang.cookie
LCTHWAFDYYDUHVZRMHIC

# rbmq02,rbmq03上设置Erlang cookie和rbmq01一样,这里以rbmq02为例
[root@rbmq02 thinktik]#vi/var/lib/rabbitmq/.erlang.cookie
[root@rbmq02 thinktik]# cat /var/lib/rabbitmq/.erlang.cookie
LCTHWAFDYYDUHVZRMHIC

这样3个条件完全满足了,我们开始架设集群

rbmq01先不动,rbmq02,rbmq03加入进来。

rbmq02 为例。rbmq03也一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# 先查看它状态,这时它是一个人
[root@rbmq02 thinktik]# rabbitmqctl cluster_status
Cluster status of node rabbit@rbmq02 ...
[{nodes,[{disc,[rabbit@rbmq02]}]},
{running_nodes,[rabbit@rbmq02]},
{cluster_name,<<"rabbit@rbmq02">>},
{partitions,[]},
{alarms,[{rabbit@rbmq02,[]}]}]

# 停止RabbitMQ application,但Erlang node会继续运行.此命令主要用于优先执行其它管理操作
[root@rbmq02 thinktik]# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rbmq02 ...
# 重置
[root@rbmq02 thinktik]# rabbitmqctl reset
Resetting node rabbit@rbmq02 ...
# 尝试加入
[root@rbmq02 thinktik]# rabbitmqctl join_cluster rabbit@rbmq01
Clustering node rabbit@rbmq02 with rabbit@rbmq01
Error: unable to perform an operation on node 'rabbit@rbmq01'. Please see diagnostics information and suggestions below.

Most common reasons for this are:

* Target node is unreachable (e.g. due to hostname resolution, TCP connection or firewall issues)
* CLI tool fails to authenticate with the server (e.g. due to CLI tool's Erlang cookie not matching that of the server)
* Target node is not running

In addition to the diagnostics info below:

* See the CLI, clustering and networking guides on http://rabbitmq.com/documentation.html to learn more
* Consult server logs on node rabbit@rbmq01
* If target node is configured to use long node names, don't forget to use --longnames with CLI tools

DIAGNOSTICS
===========

attempted to contact: [rabbit@rbmq01]

rabbit@rbmq01:
* unable to connect to epmd (port 4369) on rbmq01: address (cannot connect to host/port)
# 这里报错了,说4369端口没互相开放

Current node details:
* node name: 'rabbitmqcli-5409-rabbit@rbmq02'
* effective user's home directory: /var/lib/rabbitmq
* Erlang cookie hash: x5LJKIZbQLMWUankJiWzVQ==


# 那么我们开放这个4369端口,三个主机都开切记
[root@rbmq02 thinktik]# firewall-cmd --zone=public --add-port=4369/tcp --permanent
success
[root@rbmq02 thinktik]# firewall-cmd --reload
success

# 再次尝试
[root@rbmq02 thinktik]# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rbmq02 ...
[root@rbmq02 thinktik]# rabbitmqctl reset
Resetting node rabbit@rbmq02 ...
[root@rbmq02 thinktik]# rabbitmqctl join_cluster rabbit@rbmq01
Clustering node rabbit@rbmq02 with rabbit@rbmq01
Error: unable to perform an operation on node 'rabbit@rbmq01'. Please see diagnostics information and suggestions below.

Most common reasons for this are:

* Target node is unreachable (e.g. due to hostname resolution, TCP connection or firewall issues)
* CLI tool fails to authenticate with the server (e.g. due to CLI tool's Erlang cookie not matching that of the server)
* Target node is not running

In addition to the diagnostics info below:

* See the CLI, clustering and networking guides on http://rabbitmq.com/documentation.html to learn more
* Consult server logs on node rabbit@rbmq01
* If target node is configured to use long node names, don't forget to use --longnames with CLI tools

DIAGNOSTICS
===========

attempted to contact: [rabbit@rbmq01]

rabbit@rbmq01:
* connected to epmd (port 4369) on rbmq01
* epmd reports node 'rabbit' uses port 25672 for inter-node and CLI tool traffic
* can't establish TCP connection to the target node, reason: ehostunreach (host is unreachable)
* suggestion: check if host 'rbmq01' resolves, is reachable and ports 25672, 4369 are not blocked by firewall
# 这里继续提示25672端口和TCP连接无法建立,那么继续开25672并检查每个主机的hosts配置,三个主机都检查
Current node details:
* node name: 'rabbitmqcli-6133-rabbit@rbmq02'
* effective user's home directory: /var/lib/rabbitmq
* Erlang cookie hash: x5LJKIZbQLMWUankJiWzVQ==
# 继续开放端口 三个主机都开切记
[root@rbmq02 thinktik]# firewall-cmd --zone=public --add-port=25672/tcp --permanent
success
[root@rbmq02 thinktik]# firewall-cmd --reload
success
[root@rbmq02 thinktik]# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rbmq02 ...
[root@rbmq02 thinktik]# firewall-cmd --reload
success
# 继续尝试
[root@rbmq02 thinktik]# rabbitmqctl join_cluster rabbit@rbmq01
Clustering node rabbit@rbmq02 with rabbit@rbmq01
Error: unable to perform an operation on node 'rabbit@rbmq01'. Please see diagnostics information and suggestions below.

Most common reasons for this are:

* Target node is unreachable (e.g. due to hostname resolution, TCP connection or firewall issues)
* CLI tool fails to authenticate with the server (e.g. due to CLI tool's Erlang cookie not matching that of the server)
* Target node is not running

In addition to the diagnostics info below:

* See the CLI, clustering and networking guides on http://rabbitmq.com/documentation.html to learn more
* Consult server logs on node rabbit@rbmq01
* If target node is configured to use long node names, don't forget to use --longnames with CLI tools

DIAGNOSTICS
===========

attempted to contact: [rabbit@rbmq01]

rabbit@rbmq01:
* connected to epmd (port 4369) on rbmq01
* epmd reports node 'rabbit' uses port 25672 for inter-node and CLI tool traffic
* TCP connection succeeded but Erlang distribution failed

* Authentication failed (rejected by the remote node), please check the Erlang cookie
# 这里是检查Erlang cookie配置是否一样。我这里演示的时候起初三台没配一样。这里很好解决,直接修改3个主机cookie文件后保存在重启RabbitMQ就可以

Current node details:
* node name: 'rabbitmqcli-6711-rabbit@rbmq02'
* effective user's home directory: /var/lib/rabbitmq
* Erlang cookie hash: x5LJKIZbQLMWUankJiWzVQ==


# 三台主机hosts解析,Erlang cookie,端口开放问题逐渐排除后继续
#再试
[root@rbmq02 thinktik]# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rbmq02 ...
[root@rbmq02 thinktik]# rabbitmqctl reset
Resetting node rabbit@rbmq02 ...
# 加进去了
[root@rbmq02 thinktik]# rabbitmqctl join_cluster rabbit@rbmq01
Clustering node rabbit@rbmq02 with rabbit@rbmq01
# 看状态
[root@rbmq02 thinktik]# rabbitmqctl cluster_status
Error: this command requires the 'rabbit' app to be running on the target node. Start it with 'rabbitmqctl start_app'.
Arguments given:
cluster_status

Usage:
rabbitmqctl [-n <node>] [-l] [-q] cluster_status
# 上面的错误是要在加入后启动节点,那我启动
[root@rbmq02 thinktik]# rabbitmqctl start_app
Starting node rabbit@rbmq02 ...
completed with 3 plugins.
# 看到了(我这里rbmq03是和rbmq02同时进行了,同一时间rbmq03也进来了)
[root@rbmq02 thinktik]# rabbitmqctl cluster_status
Cluster status of node rabbit@rbmq02 ...
[{nodes,[{disc,[rabbit@rbmq01,rabbit@rbmq02,rabbit@rbmq03]}]},
{running_nodes,[rabbit@rbmq03,rabbit@rbmq01,rabbit@rbmq02]},
{cluster_name,<<"rabbit@rbmq01">>},
{partitions,[]},
{alarms,[{rabbit@rbmq03,[]},{rabbit@rbmq01,[]},{rabbit@rbmq02,[]}]}]

到这里普通集群就完成了

我们登录管理界面就看到了这3个节点

集群图片

镜像集群

这个我时间有限不仔细分析。简单的以普通集群为底子来迅速的搭建镜像

管理界面继续操作

image

也可参考https://blog.csdn.net/winy_lm/article/details/81128181

点击添加就完成了。

顺便创建几个Queue看到有效果了。镜像集群成功了
image