RabbitMQ 集群
# 180.RabbitMQ 集群
RabbitMQ 也支持集群模式
# 使用集群的原因
最开始我们介绍了如何安装及运行 RabbitMQ 服务,不过这些是单机版的,无法满足目前真实应用的要求。如果 RabbitMQ 服务器遇到内存崩溃、机器掉电或者主板故障等情况,该怎么办?
单台 RabbitMQ 服务器可以满足每秒 1000 条消息的吞吐量,那么如果应用需要 RabbitMQ 服务满足每秒 10 万条消息的吞吐量呢?购买昂贵的服务器来增强单机 RabbitMQ 务的性能显得捉襟见肘,搭建一个 RabbitMQ 集群才是解决实际问题的关键
我们可以将第一个结点为主节点,node2 和 node3 加入该主节点,作为集群:
如果想要扩展,增加多几个 RabbitMQ,是否还需加入 node1 呢?不需要。因为此时 node1、node2 和 node3 可以当作是一个整体,此时加入 node2,或 node3 都是可以的:
接下来我们搭建 3 个 RabbitMQ,架构图大致是这样的:
# 准备 3 个 Linux
首先我们准备 3 台机器,可以是虚拟机,先搭建一台,然后通过克隆的方式,复制 2 台,这样就可以有 3 台了
# 修改 hostname
我目前的 3 个 Linux 的 IP 为:192.168.56.101、192.168.56.103、192.168.56.104
为了便于理解,我们分别给每个主机重命名 hostname 为 node1,node2,node3。之前我们在 Linux 下安装的时候,已经讲过怎么修改 hostname 了:
vim /etc/sysconfig/network
HOSTNAME=node1
改 vim /etc/hostname
node1
vim /etc/hosts
127.0.0.1 localhost node1
::1 localhost node1
2
对每台机器都做这样的修改
# 配置 hosts
配置各个节点的 hosts 文件,让各个节点都能互相识别对方。
在每个机器的/etc/hosts 文件里添加如下内容:
192.168.56.101 node1
192.168.56.103 node2
192.168.56.104 node3
2
3
# 配置 cookie
我们搭建集群时,需要保证每台机器的 Erlang 使用的 cookie 是一样的,因此我们在 node1 上使用 scp 命令,将本机的 cookie 文件复制到其他两台机器上(也可以手工下载后上传,自行选择)
scp /var/lib/rabbitmq/.erlang.cookie root@node2:/var/lib/rabbitmq/.erlang.cookie
scp /var/lib/rabbitmq/.erlang.cookie root@node2:/var/lib/rabbitmq/.erlang.cookie
2
输入命令后,会提醒你是否连接,我们输入 yes,然后输入密码即可
The authenticity of host 'node2 (::1)' can't be established.
ECDSA key fingerprint is SHA256:vC9b1vwRHJGZri8PEZ6/yDajzvCHLucqa0aQqQZ+AGE.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
2
3
# 停止防火墙
为了防止结点之间因防火墙没关,导致访问失败,可以先关闭防火墙
systemctl stop firewalld
# 启动 RabbitMQ
我们需要重启 Erlang 和 RabbitMQ,在三台节点上分别执行以下命令:
rabbitmq-server -detached
然后我们在 node2 上执行命令,关闭 Erlang 虚拟机(rabbitmqctl stop_app 只关闭 RabbitMQ 服务)
rabbitmqctl stop_app
重置 RabbitMQ:
rabbitmqctl reset
加入集群:
rabbitmqctl join_cluster rabbit@node1
启动应用服务:
rabbitmqctl start_app
然后我们在 node3 上执行:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@node2
rabbitmqctl start_app
2
3
4
# 查看集群状态
在任一节点上执行:
rabbitmqctl cluster_status
显示的信息:当前节点,集群名字,有什么节点,每个节点的版本等。。。 这里列一部分
Cluster status of node rabbit@node1 ...
Basics
Cluster name: rabbit@localhost
Disk Nodes
rabbit@node1
rabbit@node2
rabbit@node3
Running Nodes
rabbit@node1
rabbit@node2
rabbit@node3
Versions
rabbit@node1: RabbitMQ 3.11.1 on Erlang 25.3
rabbit@node2: RabbitMQ 3.11.1 on Erlang 25.3
rabbit@node3: RabbitMQ 3.11.1 on Erlang 25.3
Maintenance status
Node: rabbit@node1, status: not under maintenance
Node: rabbit@node2, status: not under maintenance
Node: rabbit@node3, status: not under maintenance
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
# 新建用户
这里我们再创建一个用户,设置角色和权限:
rabbitmqctl add_user admin 123
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
2
3
此时我们可以用该用户,登录任意一个节点的后台。登录后可以看到集群信息:
状态绿色表明非常健康,由于我们重置过(之前 reset 了)所以队列是没有的,交换机也只有默认的那几个。
# 删除结点
如果我们想要去除某个结点,可以这样做(在 node2 上执行):
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
rabbitmqctl cluster_status
2
3
4
然后可以在 node1 上取消注册某个节点:
rabbitmqctl forget_cluster_node rabbit@node2
这里我们就不演示了,刚搭建好,后续还要用。感兴趣的读者可以自行测试
# 常见错误
# 没关防火墙
如果没关防火墙(或者没开放端口),加入集群的时候会报错:
# rabbitmqctl join_cluster rabbit@node1
Clustering node rabbit@node2 with rabbit@node1
Error: unable to perform an operation on node 'rabbit@node1'. 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 https://rabbitmq.com/documentation.html to learn more
* Consult server logs on node rabbit@node1
* If target node is configured to use long node names, don't forget to use --longnames with CLI tools
DIAGNOSTICS
===========
attempted to contact: [rabbit@node1]
rabbit@node1:
* unable to connect to epmd (port 4369) on node1: address (cannot connect to host/port)
Current node details:
* node name: 'rabbitmqcli-405-rabbit@node2'
* effective user's home directory: /var/lib/rabbitmq
* Erlang cookie hash: aTs+gVicVX+Yh6SnRTu6FQ==
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