RabbitMQ 教程

搭建 RabbitMQ 集群

准备工作

在正式配置 RabbitMQ 集群前,先介绍一下服务器信息,本文将搭建三台 CentOS Stream9 虚拟机,用来搭建真实的 RabbitMQ 集群服务。服务器信息如下:

  • node1:192.168.116.51

  • node2:192.168.116.52

  • node3:192.168.116.53

关于怎样在 CentOS Stream9 中安装 RabbitMQ 服务,请参考 CentOS Stream9安装RabbitMQ 文章。

注意:RabbitMQ 集群对延迟非常敏感,应当只在本地局域网内使用 。在广域网中不应该使用集群,而应该使用 Federation 或者 Shovel 来代替。

集群配置

(1)配置节点 hosts

配置各个服务器的 hosts 文件,让各个节点都能互相通过节点名访问。使用 vim 编辑 /etc/hosts 文件,内容如下:

192.168.116.51  node1
192.168.116.52  node2
192.168.116.53  node3

(2)编辑 RabbitMQ 的 cookie 文件

编辑 RabbitMQ 的 cookie 文件,确保各个节点的 cookie 文件使用的是同一个值。RabbitMQ 安装成功后都会存在一个名为 .erlang.cookie 的文件。如果是通过 RPM 包安装的 RabbitMQ,则 .erlang.cookie 文件存储在 /var/lib/rabbitmq 目录下面,如下:

[root@node1 rabbitmq]# ll -a
total 820
drwxr-xr-x.  3 rabbitmq rabbitmq     64 Apr  4 18:28 .
drwxr-xr-x. 38 root     root       4096 Apr  4 18:20 ..
-r--------.  1 rabbitmq rabbitmq     20 Apr  4 00:00 .erlang.cookie
-rw-r-----.  1 rabbitmq rabbitmq 828154 Apr  5 16:23 erl_crash.dump
drwxr-x---.  4 rabbitmq rabbitmq    119 Apr  5 16:27 mnesia

如果使用的是压缩包解压安装,则 .erlang.cookie 文件位于用户主目录下面。

下面将 node1 节点的 .erlang.cookie 文件分别拷贝到 node2 和 node3 节点。命令如下:

a、将 node1 中的 .erlang.cookie 文件拷贝到 node2 节点 /var/lib/rabbitmq 目录

[root@node1 rabbitmq]# scp /var/lib/rabbitmq/.erlang.cookie node2:/var/lib/rabbitmq
The authenticity of host 'node2 (192.168.116.52)' can't be established.
ED25519 key fingerprint is SHA256:SgZXx0DQzxZVKm4QbyYW0F64Mb8ZUdJgZdVhU40Hzak.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? y
Please type 'yes', 'no' or the fingerprint: yes
Warning: Permanently added 'node2' (ED25519) to the list of known hosts.
root@node2's password: 
.erlang.cookie                                                                                                                                                                  100%   20    18.9KB/s   00:00

b、将 node1 中的 .erlang.cookie 文件拷贝到 node3 节点 /var/lib/rabbitmq 目录

[root@node1 rabbitmq]# scp /var/lib/rabbitmq/.erlang.cookie node3:/var/lib/rabbitmq
The authenticity of host 'node3 (192.168.116.53)' can't be established.
ED25519 key fingerprint is SHA256:SgZXx0DQzxZVKm4QbyYW0F64Mb8ZUdJgZdVhU40Hzak.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:1: node2
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'node3' (ED25519) to the list of known hosts.
root@node3's password: 
.erlang.cookie                                                                                                                                                                  100%   20     9.1KB/s   00:00

(3)配置集群

配置集群有三种方式:

  • 通过 rabbitmqctl 工具进行配置

  • 通过 rabbitmq.config 配置文件配置

  • 通过 rabbitmq-autocluster 插件配置

下面主要介绍通过 rabbitmqctl 工具的方式进行集群配置,这也是最常用的方式。

首先启动 node1、node2 和 node3 三个节点的 RabbitMQ 服务,命令如下:

[root@node1 rabbitmq]# rabbitmq-server -detached
[root@node2 rabbitmq]# rabbitmq-server -detached
[root@node3 rabbitmq]# rabbitmq-server -detached

上面虽然成功启动了三个服务,但是它们都是以独立节点存在的。可通过命令来查看各个节点的状态。命令如下:

[root@node1 rabbitmq]# rabbitmqctl cluster_status
Cluster status of node rabbit@node1 ...
Basics
Cluster name: rabbit@node1

Disk Nodes
rabbit@node1

Running Nodes
rabbit@node1

Versions
rabbit@node1: RabbitMQ 3.9.14 on Erlang 24.3.3
...

分别在 node2 和 node3 节点上执行上面命令,它们都是独立的节点。

接下来,将以 node1 节点为基准,将 node2 和 node3 节点加入 node1 节点的集群中。注意,这三个节点是平等的,如果想要调换彼此的加入顺序也是可以的。

首先,将 node2 节点加入 node1 节点的集群中,需要执行如下4个命令步骤:

[root@node2 rabbitmq]# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@node2 ...

[root@node2 rabbitmq]# rabbitmqctl reset
Resetting node rabbit@node2 ...

[root@node2 rabbitmq]# rabbitmqctl join_cluster rabbit@node1
Clustering node rabbit@node2 with rabbit@node1

[root@node2 rabbitmq]# rabbitmqctl start_app
Starting node rabbit@node2 ...

其中:

  • rabbitmqctl stop_app:命令用于停止应用程序;

  • rabbitmqctl reset:命令用于指示 RabbitMQ 节点离开集群并返回其原始状态;

  • rabbitmqctl join_cluster rabbit@node1:命令用于将当前 RabbitMQ 节点加入到 node1 节点;

  • rabbitmqctl start_app:命令用于启动应用程序;

最后,按照上面同样的命令将 node3 添加到 node1 节点集群。再使用命令查看节点状态:

[root@node1 rabbitmq]# rabbitmqctl cluster_status
Cluster status of node rabbit@node1 ...
Basics
Cluster name: rabbit@node1

Disk Nodes
rabbit@node1
rabbit@node2
rabbit@node3

Running Nodes
rabbit@node1
rabbit@node2
rabbit@node3

Versions
rabbit@node1: RabbitMQ 3.9.14 on Erlang 24.3.3
rabbit@node2: RabbitMQ 3.9.14 on Erlang 24.3.3
rabbit@node3: RabbitMQ 3.9.14 on Erlang 24.3.3
...

到这里,我们成功完成 RabbitMQ 集群搭建。你也可以使用 rabbitmq_management 插件查看集群状态,如下图:

如果此时我们使用 rabbitmqctl stop 命令主动关闭 node3 节点的 RabbitMQ 服务,再使用 rabbitmqctl cluster_status 命令查看集群状态如下:

[root@node1 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@node1 ...
Basics
Cluster name: rabbit@node1

Disk Nodes
rabbit@node1
rabbit@node2
rabbit@node3

Running Nodes
rabbit@node1
rabbit@node2

Versions
rabbit@node1: RabbitMQ 3.9.14 on Erlang 24.3.3
rabbit@node2: RabbitMQ 3.9.14 on Erlang 24.3.3
...

注意,此时正在运行的节点就只有 rabbit@node1 和 rabbit@node2 了。

如果关闭了集群中的所有节点,则需要确保在启动的时候,最后关闭的那个节点是第一个启动的节点。如果第一个启动的节点不是最后关闭的节点,那么这个节点会等待(等待时间为 30 秒)最后关闭的节点启动。如果过了等待时间还是没有等到,那么这个先启动的节点会继续尝试等待(默认等待 9 次数)。错误日志如下:

2022-04-06 12:53:54.280197+08:00 [info] <0.229.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2022-04-06 12:54:24.283923+08:00 [warning] <0.229.0> Error while waiting for Mnesia tables: {timeout_waiting_for_tables,
2022-04-06 12:54:24.283923+08:00 [warning] <0.229.0>                                         [rabbit@node3,rabbit@node2,
2022-04-06 12:54:24.283923+08:00 [warning] <0.229.0>                                          rabbit@node1],
2022-04-06 12:54:24.283923+08:00 [warning] <0.229.0>                                         [rabbit_durable_queue]}
2022-04-06 12:54:24.284059+08:00 [info] <0.229.0> Waiting for Mnesia tables for 30000 ms, 8 retries left
2022-04-06 12:54:54.286581+08:00 [warning] <0.229.0> Error while waiting for Mnesia tables: {timeout_waiting_for_tables,
...

如果该节点已经等待默认尝试次数,依然没有等到,则节点又会继续重新等待 9 次。如下:

2022-04-06 12:58:54.309873+08:00 [warning] <0.229.0> Feature flags: the previous instance of this node must have failed to write the `feature_flags` file at `/var/lib/rabbitmq/mnesia/rabbit@node2-feature_flags`:
2022-04-06 12:58:54.309979+08:00 [warning] <0.229.0> Feature flags:   - list of previously disabled feature flags now marked as such: [empty_basic_get_metric]
2022-04-06 12:58:54.312145+08:00 [info] <0.229.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
...

如果最后一个关闭的节点最终由于某些异常而无法正常启动,则可以通过 rabbitmqctl forget_cluster_node 命令来将此节点从当前集群踢出。

如果集群中的所有节点由于某些非正常因素,比如断电而关闭,那么集群中的节点都会认为还有其他节点在它后面被关闭,此时需要调用 rabbitrnqctl force_boot 命令来启动一个节点,之后集群才能正常启动。

说说我的看法
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号