RabbitMQ的安装集群、镜像队列配置

1 RabbitMQ集群简介

RabbitMQ 集群是一个或多个节点的逻辑分组,每个节点共享用户、虚拟主机、队列、流、交换机、绑定、运行时参数和其他分布式状态。

集群中的节点名称必须是唯一的。在集群中,节点使用节点名称来识别和相互联系。这意味着每个节点名称的主机名部分必须可以解析。CLI 工具也使用节点名称来识别和寻址节点。当节点启动时,它会检查是否已为其分配了节点名称。如果未显式配置值,则节点会解析其主机名并在其前面加上rabbit@ 以计算其节点名称。

RabbitMQ代理操作所需的所有数据/状态都在所有节点之间复制。消息队列是此规则的例外,默认情况下消息队列驻留在一个节点上,但可以从所有节点查看和访问。要在集群中的节点之间复制队列,请使用支持复制的队列类型。

一般提到的RabbitMQ镜像集群,实际上由集群加上经典消息队列的镜像复制策略构成。RabbitMQ 4.0及后续版本不再支持经典消息队列的镜像复制功能,因此本例采用RabbitMQ 3.13.7版实现。

2 安装配置规划

配置项 主机一 主机二
IP地址 10.10.1.45 10.10.1.46
主机名称 KL5 KL6
配置用户 kylin kylin
安装文件目录 /home/kylin/Install /home/kylin/Install
消息队列目录 /data/rabbitmq /data/rabbitmq
相关端口 使用默认值 使用默认值
MQ测试用户 test/password
MQ虚拟主机 /test/
镜像策略名 jxjq

3 安装RabbitMQ

3.1 安装版本说明

RabbitMQ仅4.0以下版本支持经典队列镜像,因此本例选择RabbitMQ 3.x版本中最新的3.13.7版。根据官方网站上RabbitMQ与Erlang的版本兼容性矩阵,Erlang版本选择26.x中最新的26.2.5.15。

银河麒麟V10的桌面版和服务器版的安装体系差异很大,默认已经安装的包也不同,因此在安装Erlang之前,银河麒麟V10的桌面版和服务器版需要安装不同的包。本例基于以下银河麒麟版本建立。

Kylin-Desktop-V10-GFB-HWE-Release-020-X86_64

Kylin-Desktop-V10-GFB-020-Release-20.1.3-ARM64

Kylin-Server-V10-GFB-Release-030-X86_64

Kylin-Server-V10-GFB-030-Release-30.1.3-ARM64

3.2 麒麟V10桌面版(GFB)

3.2.1 安装前准备

使用管理员用户,创建安装文件目录。

复制代码
kylin@KL5:~$ mkdir Install

3.2.2 安装ncurses

3.2.2.1 使用deb包安装

银河麒麟V10桌面版(GFB)默认已安装libtinfo6、libncurses6、libncursesw6,版本为6.2-0kylin2,需要安装对应版本的libncurses-dev。本例拿到的是6.2-0kylin2.1版本,因为依赖关系除安装libncurses-dev外,需要安装对应版本的libtinfo6、libncurses6、libncursesw6。

使用管理员账户,执行dpkg -i命令安装libncurses-dev及其依赖包。

复制代码
kylin@KL5:~/Install$ sudo dpkg -i libncurses-dev_6.2-0kylin2.1_amd64.deb libtinfo6_6.2-0kylin2.1_amd64.deb libncurses6_6.2-0kylin2.1_amd64.deb libncursesw6_6.2-0kylin2.1_amd64.deb
正在选中未选择的软件包 libncurses-dev:amd64。
(正在读取数据库 ... 系统当前共安装有 187718 个文件和目录。)
准备解压 libncurses-dev_6.2-0kylin2.1_amd64.deb  ...
正在解压 libncurses-dev:amd64 (6.2-0kylin2.1) ...
准备解压 libtinfo6_6.2-0kylin2.1_amd64.deb  ...
正在解压 libtinfo6:amd64 (6.2-0kylin2.1) 并覆盖 (6.2-0kylin2) ...
准备解压 libncurses6_6.2-0kylin2.1_amd64.deb  ...
正在解压 libncurses6:amd64 (6.2-0kylin2.1) 并覆盖 (6.2-0kylin2) ...
准备解压 libncursesw6_6.2-0kylin2.1_amd64.deb  ...
正在解压 libncursesw6:amd64 (6.2-0kylin2.1) 并覆盖 (6.2-0kylin2) ...
正在设置 libtinfo6:amd64 (6.2-0kylin2.1) ...
正在设置 libncurses6:amd64 (6.2-0kylin2.1) ...
正在设置 libncursesw6:amd64 (6.2-0kylin2.1) ...
正在设置 libncurses-dev:amd64 (6.2-0kylin2.1) ...
正在处理用于 man-db (2.9.1-1kylin0k1) 的触发器 ...
正在处理用于 libc-bin (2.31-0kylin9.1k20.8) 的触发器 ...

如果无法获取麒麟官方安装包,可以下载debian提供的包,版本为6.2+20201114-2或其他接近版本。可以使用中科大的镜像网站

3.2.2.2 使用源代码安装

gnu官方网站下载最新版本的源代码包ncurses-6.5.tar.gz,放置到安装目录。解压缩后进入解压后的目录,执行configure命令。

复制代码
kylin@KL5:~/Install$ tar -zxf ncurses-6.5.tar.gz
kylin@KL5:~/Install$ cd ncurses-6.5/
kylin@KL5:~/Install/ncurses-6.5$ ./configure
checking for ggrep... no
checking for grep... grep
checking for egrep... grep -E
Configuring NCURSES 6.5 ABI 6 (Fri Sep 19 10:43:14 CST 2025)
............
这里很多提示信息,此处省略。
............
** Configuration summary for NCURSES 6.5 20240427:
       extended funcs: yes
       xterm terminfo: xterm-new
        bin directory: /usr/bin
        lib directory: /usr/lib
    include directory: /usr/include
        man directory: /usr/share/man
   terminfo directory: /usr/share/terminfo

继续执行make指令进行编译。

复制代码
kylin@KL5:~/Install/ncurses-6.5$ make
( cd man && make DESTDIR="" RPATH_LIST="/usr/lib" all )
make[1]: 进入目录"/home/kylin/Install/ncurses-6.5/man"
/bin/sh ./MKterminfo.sh ./terminfo.head ./../include/Caps ./../include/Caps-ncurses ./terminfo.tail >terminfo.5
............
这里很多提示信息,此处省略。
............
compiling demo (obj_s)
/usr/bin/g++  -o demo ../objects/demo.o -L../lib -lncurses++w -L../lib -lformw -lmenuw -lpanelw -lncursesw   -lutil     -DHAVE_CONFIG_H -DBUILDING_NCURSES_CXX -I../c++ -I. -I../include -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -DNDEBUG -O2  -DNCURSES_STATIC
make[1]: 离开目录"/home/kylin/Install/ncurses-6.5/c++"

编译成功后,用管理员账户执行make install安装。

复制代码
kylin@KL5:~/Install/ncurses-6.5$ sudo make install
( cd man && make DESTDIR="" RPATH_LIST="/usr/lib" install )
make[1]: 进入目录"/home/kylin/Install/ncurses-6.5/man"
/bin/sh ../edit_man.sh normal installing /usr/share/man . terminfo.5 *-config.1 ./*.[0-9]* ...made /home/kylin/Install/ncurses-6.5/man_alias.sed
............
这里很多提示信息,此处省略。
............
installing ./cursesapp.h in /usr/include
installing ./cursesf.h in /usr/include
installing ./cursesm.h in /usr/include
installing ./cursesp.h in /usr/include
installing ./cursesw.h in /usr/include
installing ./cursslk.h in /usr/include
installing etip.h in /usr/include
make[1]: 离开目录"/home/kylin/Install/ncurses-6.5/c++"

3.2.3 安装OpenSSL

OpenSSL官方网站下载指定版本的源代码包openssl-1.1.1w.tar.gz,放置到安装目录。解压缩openssl-OpenSSL_1_1_1w.zip,进入解压后的目录。

复制代码
kylin@KL5:~/Install$ unzip openssl-OpenSSL_1_1_1w.zip
Archive:  openssl-OpenSSL_1_1_1w.zip
e04bd3433fd84e1861bf258ea37928d9845e6a86
   creating: openssl-OpenSSL_1_1_1w/
  inflating: openssl-OpenSSL_1_1_1w/ACKNOWLEDGEMENTS
  inflating: openssl-OpenSSL_1_1_1w/AUTHORS
  inflating: openssl-OpenSSL_1_1_1w/CHANGES
  inflating: openssl-OpenSSL_1_1_1w/CONTRIBUTING
............
这里很多提示信息,此处省略。
............
  inflating: openssl-OpenSSL_1_1_1w/util/shlib_wrap.sh.in
  inflating: openssl-OpenSSL_1_1_1w/util/su-filter.pl
  inflating: openssl-OpenSSL_1_1_1w/util/unlocal_shlib.com.in
   creating: openssl-OpenSSL_1_1_1w/wycheproof/
kylin@KL5:~/Install$ cd openssl-OpenSSL_1_1_1w/

执行config命令指定安装目录进行配置。

复制代码
kylin@KL5:~/Install/openssl-OpenSSL_1_1_1w$ ./config --prefix=/usr/local/openssl
Operating system: x86_64-whatever-linux2
Configuring OpenSSL version 1.1.1w (0x1010117fL) for linux-x86_64
Using os-specific seed configuration
Creating configdata.pm
Creating Makefile
**********************************************************************
***                                                                ***
***   OpenSSL has been successfully configured                     ***
***                                                                ***
***   If you encounter a problem while building, please open an    ***
***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
***   and include the output from the following command:           ***
***                                                                ***
***       perl configdata.pm --dump                                ***
***                                                                ***
***   (If you are new to OpenSSL, you might want to consult the    ***
***   'Troubleshooting' section in the INSTALL file first)         ***
***                                                                ***
**********************************************************************

继续执行make指令进行编译。

复制代码
kylin@KL5:~/Install/openssl-OpenSSL_1_1_1w$ make
/usr/bin/perl "-I." -Mconfigdata "util/dofile.pl" \
    "-oMakefile" include/crypto/bn_conf.h.in > include/crypto/bn_conf.h
/usr/bin/perl "-I." -Mconfigdata "util/dofile.pl" \
    "-oMakefile" include/crypto/dso_conf.h.in > include/crypto/dso_conf.h
/usr/bin/perl "-I." -Mconfigdata "util/dofile.pl" \
    "-oMakefile" include/openssl/opensslconf.h.in > include/openssl/opensslconf.h
make depend && make _all
............
这里很多提示信息,此处省略。
............
/usr/bin/perl "-I." -Mconfigdata "util/dofile.pl" \
    "-oMakefile" util/shlib_wrap.sh.in > "util/shlib_wrap.sh"
chmod a+x util/shlib_wrap.sh
make[1]: Leaving directory '/home/kylin/Install/openssl-OpenSSL_1_1_1w'

编译成功后,用管理员账户执行make install安装。

复制代码
kylin@KL5:~/Install/openssl-OpenSSL_1_1_1w$ sudo make install
make depend && make _build_libs
make[1]: Entering directory '/home/kylin/Install/openssl-OpenSSL_1_1_1w'
make[1]: Leaving directory '/home/kylin/Install/openssl-OpenSSL_1_1_1w'
make[1]: Entering directory '/home/kylin/Install/openssl-OpenSSL_1_1_1w'
make[1]: Nothing to be done for '_build_libs'.
make[1]: Leaving directory '/home/kylin/Install/openssl-OpenSSL_1_1_1w'
............
这里很多提示信息,此处省略。
............
/usr/local/openssl/share/doc/openssl/html/man7/SM2.html
/usr/local/openssl/share/doc/openssl/html/man7/ssl.html
/usr/local/openssl/share/doc/openssl/html/man7/X25519.html
/usr/local/openssl/share/doc/openssl/html/man7/X448.html -> /usr/local/openssl/share/doc/openssl/html/man7/X25519.html
/usr/local/openssl/share/doc/openssl/html/man7/x509.html

3.3 麒麟V10高级服务器版(GFB)

3.3.1 安装前准备

银河麒麟V10高级服务器版,允许使用root直接登录,这里安全起见,创建用户kylin并加入wheel组,作为管理员用户使用。

复制代码
[root@localhost ~]# adduser kylin
[root@localhost ~]# passwd kylin
更改用户 kylin 的密码 。
新的 密码:
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]# usermod -aG wheel kylin

再使用root用户创建/data共享目录。

复制代码
[root@localhost ~]# mkdir /data
[root@localhost ~]# chmod a+rwx /data
[root@localhost ~]# chmod -t /data

使用root用户修改主机名,并重新登录。

复制代码
[root@localhost ~]# hostnamectl set-hostname KL5
[root@localhost ~]# logout

使用kylin用户创建目录Install用于放置所有安装文件。

复制代码
[kylin@KL5 ~]$ mkdir Install

3.3.2 安装ncurses

在麒麟V10高级服务器版扩展盘中可以找到ncurses-devel的RPM包,其中x86版文件名为"ncurses-devel-6.2-3.gfb03.ky10.x86_64.rpm",ARM版文件名为"ncurses-devel-6.2-3.gfb03.ky10.aarch64.rpm"。使用管理员账户安装RPM包。

复制代码
[kylin@KL5 Install]$ sudo rpm -i ncurses-devel-6.2-3.gfb03.ky10.x86_64.rpm
警告:ncurses-devel-6.2-3.gfb03.ky10.x86_64.rpm: 头V4 RSA/SHA1 Signature, 密钥 ID 34fe765a: NOKEY

3.4 安装Erlang

Erlang官网网站下载指定版本的源代码包otp_src_26.2.5.15.tar.gz,放置到安装目录。解压缩安装包后进入解压后的目录,执行configure命令。

复制代码
[kylin@KL5 Install]$ tar -zxf otp_src_26.2.5.15.tar.gz
[kylin@KL5Install]$ cd otp_src_26.2.5.15/ 
[kylin@KL5 otp_src_26.2.5.15]$ ./configure
=== Running configure in /home/kylin/Install/otp_src_26.2.5.15/erts ===
./configure --disable-option-checking --cache-file=/dev/null --srcdir="/home/kylin/Install/otp_src_26.2.5.15/erts"
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
............
这里很多提示信息,此处省略。
............
*********************************************************************

在配置Erlang的时候会提示因为缺少ODBC library、GLU headers等,导致odbc、wx等不可用,这个不影响RabbitMQ的一般使用,暂时不用理会。

继续执行make指令进行编译。

复制代码
[kylin@KL5 otp_src_26.2.5.15]$ make
 MAKE   depend
make[1]: 进入目录"/home/kylin/Install/otp_src_26.2.5.15/erts/emulator"
 MAKE   generate
make[2]: 进入目录"/home/kylin/Install/otp_src_26.2.5.15/erts/emulator"
 GEN    x86_64-pc-linux-gnu/opt/jit/OPCODES-GENERATED
 GEN    x86_64-pc-linux-gnu/opt/jit/beam_asm_global.hpp
............
这里很多提示信息,此处省略。
............
 GEN    /home/kylin/Install/otp_src_26.2.5.15/bin/start.script
 GEN    /home/kylin/Install/otp_src_26.2.5.15/bin/start_sasl.script
 GEN    /home/kylin/Install/otp_src_26.2.5.15/bin/start_clean.script
 GEN    /home/kylin/Install/otp_src_26.2.5.15/bin/no_dot_erlang.script
make[2]: 离开目录"/home/kylin/Install/otp_src_26.2.5.15/erts/start_scripts"
make[1]: 离开目录"/home/kylin/Install/otp_src_26.2.5.15/erts"

编译成功后,用管理员账户执行make install安装。

复制代码
[kylin@KL5 otp_src_26.2.5.15]$ sudo make install
MAKE   erl_interface
make[1]: 进入目录"/home/kylin/Install/otp_src_26.2.5.15/lib/erl_interface"
=== Entering application erl_interface
make[2]: 进入目录"/home/kylin/Install/otp_src_26.2.5.15/lib/erl_interface/src"
............
这里很多提示信息,此处省略。
............
ln -s ../lib/erlang/bin/dialyzer dialyzer
ln -s ../lib/erlang/bin/typer typer
ln -s ../lib/erlang/bin/escript escript
ln -s ../lib/erlang/bin/ct_run ct_run
[kylin@KL5 otp_src_26.2.5.15]$

测试Erlang,使用erl命令进入Erlang控制台,使用crypto:start测试OpenSSL,使用halt命令退出。

复制代码
[kylin@KL5 otp_src_26.2.5.15]$ erl
Erlang/OTP 26 [erts-14.2.5.11] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [jit:ns]
Eshell V14.2.5.11 (press Ctrl+G to abort, type help(). for help)
1> crypto:start().
ok
2> halt().

3.5 安装RabbitMQ

解压缩rabbitmq-server-generic-unix-3.13.7.tar.xz,将解压后的目录移动到指定位置。

复制代码
[kylin@KL5 Install]$ tar -xf rabbitmq-server-generic-unix-3.13.7.tar.xz
[kylin@KL5 Install]$ mv rabbitmq_server-3.13.7/ /data/rabbitmq

编辑配置文件/etc/profile,将/data/rabbitmq/sbin加入到PATH环境变量中,使用source /etc/profile命令更新环境变量。

复制代码
[kylin@KL5 Install]$ sudo vi /etc/profile
............
其他配置内容。
............
export PATH=$PATH:/data/rabbitmq/sbin
[kylin@KL5 Install]$ source /etc/profile

使用rabbitmq-server -detached以后台服务方式启动RabbitMQ,使用rabbitmqctl status查看RabbitMQ状态,可以看到RabbitMQ开启了5672端口和25672端口,分别服务于amqp和clustering协议。

复制代码
[kylin@KL5 ~]$ rabbitmq-server -detached
[kylin@KL5 ~]$ rabbitmqctl status
Status of node rabbit@localhost ...cha
Runtime
OS PID: 122102
OS: Linux
Uptime (seconds): 7
Is under maintenance?: false
RabbitMQ version: 3.13.7
............
此处有很多状态信息,此处忽略。
............
Listeners
Interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0

使用rabbitmqctl start_app和rabbitmq-plugins enable rabbitmq_management命令开启管理控制台,再使用rabbitmqctl status查看RabbitMQ状态,可以看到15672端口已经打开,此时可以使用浏览器管理消息队列。

复制代码
[kylin@KL5 ~]$ rabbitmqctl start_app
rabbitmqctl start_app
Starting node rabbit@localhost ...

[kylin@KL5 ~]$ rabbitmq-plugins enable rabbitmq_management
rabbitmq-plugins enable rabbitmq_management
Enabling plugins on node rabbit@localhost:
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. 

[kylin@KL5 ~]$ rabbitmqctl status
Status of node rabbit@localhost ...
Runtime
............
此处有很多状态信息,此处忽略。
............
Listeners
Interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Interface: [::], port: 15672, protocol: http, purpose: HTTP API

3.6 注册RabbitMQ为服务

使用管理员用户编辑/etc/systemd/system/rabbitmq.service文件,在文件中加入如下内容。

复制代码
[kylin@KL5 ~]$ sudo vi /etc/systemd/system/rabbitmq.service

[Unit]
Description = RabbitMQ Server
After = network.target

[Service]
Type = simple
User = kylin
Group = kylin
ExecStart = /data/rabbitmq/sbin/rabbitmq-server
ExecStop = /data/rabbitmq/sbin/rabbitmqctl stop
Restart = on-failure
RestartSec = 60s
LimitNOFILE = 65536

[Install]
WantedBy = multi-user.target

重新加载服务,将服务设置为开机启动。

复制代码
[kylin@KL5 system]$ sudo systemctl daemon-reload
[kylin@KL5 system]$ sudo systemctl enable rabbitmq
Created symlink /etc/systemd/system/multi-user.target.wants/rabbitmq.service → /etc/systemd/system/rabbitmq.service.

启动服务并查看服务状态。如果之前RabbitMQ已启动,先结束进程。

复制代码
[kylin@KL5 ~]$ ps -AL|grep beam
   2212    2212 ?        00:00:00 beam.smp
[kylin@KL5 ~]$ kill 2212
[kylin@KL5 ~]$ sudo systemctl start rabbitmq
[kylin@KL5 ~]$ sudo systemctl status rabbitmq
● rabbitmq.service - RabbitMQ Server
   Loaded: loaded (/etc/systemd/system/rabbitmq.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2025-09-24 10:24:47 CST; 2s ago
 Main PID: 1012826 (rabbitmq-server)
    Tasks: 26
   Memory: 124.6M
   CGroup: /system.slice/rabbitmq.service
           ├─1012826 /bin/sh /data/rabbitmq/sbin/rabbitmq-server
           ├─1012833 /usr/local/lib/erlang/erts-14.2.5.11/bin/beam.smp -W w -MBas ageffcbf -MHas ageffcbf -MBlmbcs 512 -MHlmbcs 512 -MMmcs 30 -pc unicode -P 1048576 -t 5000000 -stbt db -zdbbl >
           ├─1012839 erl_child_setup 65536
           ├─1012858 sh -s disksup
           ├─1012860 /usr/local/lib/erlang/lib/os_mon-2.9.1/priv/bin/memsup
           ├─1012861 /usr/local/lib/erlang/lib/os_mon-2.9.1/priv/bin/cpu_sup
           ├─1012862 /usr/local/lib/erlang/erts-14.2.5.11/bin/inet_gethost 4
           ├─1012863 /usr/local/lib/erlang/erts-14.2.5.11/bin/inet_gethost 4
           └─1012916 /bin/sh -s rabbit_disk_monitor

4 配置RabbitMQ集群

4.1 修改hosts文件

修改/etc/hosts文件,将集群涉及的主机名称添加到hosts文件中。

复制代码
kylin@KL5:~$ sudo vi /etc/hosts
127.0.0.1       localhost
10.10.1.45      KL5
10.10.1.46      KL6

4.2 开放防火墙端口

麒麟高级服务器版默认开启了防火墙,需要开放RabbitMQ相关的端口,包括4369(EPMD)、5671-5672(AMQP)、15672(管理页面)、25672(节点间通讯)、35672-35682(CLI工具)等,以上端口均为TCP协议。

复制代码
[kylin@KL5 ~]$ sudo firewall-cmd --add-port=4369/tcp --permanent
success
[kylin@KL5 ~]$ sudo firewall-cmd --add-port=5671-5672/tcp --permanent
success
[kylin@KL5 ~]$ sudo firewall-cmd --add-port=15672/tcp --permanent
success
[kylin@KL5 ~]$ sudo firewall-cmd --add-port=25672/tcp --permanent
success
[kylin@KL5 ~]$ sudo firewall-cmd --add-port=35672-35682/tcp --permanent
success
[kylin@KL5 ~]$ sudo firewall-cmd --reload
success
[kylin@KL5 ~]$ sudo firewall-cmd --list-ports
4369/tcp 15672/tcp 25672/tcp 35672-35682/tcp 5671-5672/tcp

4.3 复制cookie文件

将.erlang.cookie从主机服务器复制到其他服务器相同目录。本例中.erlang.cookie文件在kylin用户目录下。如果提示没有权限,需要先修改从机上的文件权限。

复制代码
kylin@KL5:~$ scp .erlang.cookie kylin@KL6:/home/kylin
kylin@KL6's password:
.erlang.cookie                                              100%   20     7.8KB/s   00:00

修改.erlang.cookie文件之前如果已经用rabbitmq-server启动了消息队列,在修改.erlang.cookie文件会无法使用rabbitmqctl控制,需要结束进程,rabbitmq的进程名称为beam.smp。

复制代码
[kylin@KL5 ~]$ ps -AL|grep beam.smp
  33029   33029 ?        00:00:00 beam.smp
[kylin@KL5 ~]$ kill 33029

4.4 将从机加入集群

分别启动主机和从机的服务后,在从机上使用rabbitmqctl stop_app指令停止应用,使用rabbitmqctl join_cluster指令将从机加入主机集群,再使用rabbitmqctl start_app指令启动应用。此时可以使用rabbitmqctl cluster_status指令查看集群状态。

复制代码
kylin@KL6:~$ rabbitmqctl stop_app
Stopping rabbit application on node rabbit@KL6 ...

kylin@KL6:~$ rabbitmqctl join_cluster rabbit@KL5
Clustering node rabbit@KL6 with rabbit@KL5

kylin@KL6:~$ rabbitmqctl start_app
Starting node rabbit@KL6 ...

kylin@KL6:~$ rabbitmqctl cluster_status
Cluster status of node rabbit@KL6 ...
Basics
Cluster name: rabbit@KL6
Total CPU cores available cluster-wide: 8
Cluster Tags
(none)
Disk Nodes
rabbit@KL5
rabbit@KL6
Running Nodes
rabbit@KL5
rabbit@KL6
Versions
rabbit@KL6: RabbitMQ 3.13.7 on Erlang 26.2.5.15
rabbit@KL5: RabbitMQ 3.13.7 on Erlang 26.2.5.15
CPU Cores
Node: rabbit@KL6, available CPU cores: 4
Node: rabbit@KL5, available CPU cores: 4
Maintenance status
Node: rabbit@KL6, status: not under maintenance
Node: rabbit@KL5, status: not under maintenance
............
此处有很多状态信息,此处忽略。
............

此时,集群已经建立,但模式为普通模式,下一步需要将队列配置为镜像模式。配置可以采用管理页面方式,也可以使用命令行方式配置。

4.5 配置镜像策略

4.5.1 页面方式配置镜像

使用浏览器打开主机的配置页面,使用默认用户guest/guest登录,创建需要的用户、虚拟主机、交换机、消息队列等,在创建消息队列时选择classic类型。

使用有管理员权限用户登录,在Admin->Policies->User Policies管理项下,增加管理策略。Pattern填写"^",Apply to选择"Exchanges and queues",Definition定义"ha-mode=all"、"ha-sync-mode=automatic"。

4.5.2 命令方式配置镜像

使用rabbitmqctl set_policy命令设置复制策略。

复制代码
[kylin@KL5 ~]$ rabbitmqctl set_policy jxjq "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}' -p /test/
Setting policy "jxjq" for pattern "^" to "{"ha-mode":"all","ha-sync-mode":"automatic"}" with priority "0" for vhost "/test/" ...

其中"jxjq"为策略名称,"^"为匹配字符,"{"ha-mode":"all","ha-sync-mode":"automatic"}'"为JSON格式的策略定义,"-p /test/"表示应用的Virtual host。

5 集群切换测试

集群启动-后,连接管理页面可以查看集群状态、队列状态,此时队列显示主节点为KL5,KL5为集群主机,KL6为集群从机。

在正常状态下,测试向消息队列faultQueue发送了6条数据。

通过暂停虚拟机的方式,将KL5主机暂停。在KL5主机暂停的最初十几秒内,从机上的消息队列暂时不可连接,管理页面也没有响应,应该在切换集群主从。之后可正常连接从机上的消息队列,收发消息,管理页面可以看到KL5节点变成停止状态,消息队列显示主节点为KL6,KL6为集群主机。

在KL5故障状态下,向消息队列faultQueue又发送了8条数据,现在KL6显示共有14条数据。

通过查看运行日志,可以看到节点KL6已经发现KL5无法连接了。

复制代码
[kylin@KL6 ~]$ tail -f /data/rabbitmq/var/log/rabbitmq/rabbit@KL6.log
2025-09-24 14:08:59.801496+08:00 [error] <0.2019.0> ** Node rabbit@KL5 not responding **
2025-09-24 14:08:59.801496+08:00 [error] <0.2019.0> ** Removing (timedout) connection **
2025-09-24 14:08:59.801496+08:00 [error] <0.2019.0>
2025-09-24 14:08:59.802145+08:00 [info] <0.5951.0> rabbit on node rabbit@KL5 down
2025-09-24 14:09:02.910433+08:00 [warning] <0.6301.0> Management delegate query returned errors:
2025-09-24 14:09:02.910433+08:00 [warning] <0.6301.0> [{<30547.2322.0>,{exit,{nodedown,rabbit@KL5},[]}}]
2025-09-24 14:09:02.910772+08:00 [warning] <0.6302.0> Management delegate query returned errors:
2025-09-24 14:09:02.910772+08:00 [warning] <0.6302.0> [{<30547.2322.0>,{exit,{nodedown,rabbit@KL5},[]}}]
2025-09-24 14:09:02.911090+08:00 [info] <0.5951.0> node rabbit@KL5 down: net_tick_timeout

使用命令行方式,也可以看到集群节点包括KL5和KL6,但目前只有KL6运行。

复制代码
[kylin@KL6 ~]$ rabbitmqctl cluster_status
Cluster status of node rabbit@KL6 ...
Basics
Cluster name: rabbit@KL6
Total CPU cores available cluster-wide: 1
Disk Nodes
rabbit@KL5
rabbit@KL6
Running Nodes
rabbit@KL6
............
这里很多状态信息,此处省略。
............

此时恢复虚拟机,将KL5主机恢复并接入。正常情况下集群恢复,但集群主节点仍然是KL6。

通过查看KL6的日志,可以看到集群已经发现KL5苏醒,并选举KL6继续做主节点,并等待KL5重新加入集群。

复制代码
2025-09-24 14:39:09.201846+08:00 [info] <0.13111.0> node rabbit@KL5 up
2025-09-24 14:39:09.220700+08:00 [info] <0.13111.0> Autoheal: I am the winner, waiting for [rabbit@KL5] to stop
2025-09-24 14:40:10.813167+08:00 [info] <0.13111.0> rabbit on node rabbit@KL5 up
2025-09-24 14:40:10.816809+08:00 [info] <0.13247.0> Mirrored queue 'dataQueue' in vhost '/test/': Synchronising: 0 messages to synchronise

通过查看KL5的日志,也可以看到KL5选举失败,重新启动并加入了集群。

复制代码
2025-09-24 14:39:09.541787+08:00 [info] <0.2163.0> Successfully stopped RabbitMQ and its dependencies
2025-09-24 14:39:19.222195+08:00 [warning] <0.2278.0> Mnesia->Khepri fallback handling: Mnesia function failed 99 times. Possibly an infinite retry loop; trying one last time
2025-09-24 14:40:09.542739+08:00 [warning] <0.2163.0> Autoheal: timed out waiting for a safe-to-start message from the winner (rabbit@KL6); will retry
2025-09-24 14:40:09.542924+08:00 [info] <0.2163.0> RabbitMQ is asked to start...
............
这里很多状态信息,此处省略。
............
2025-09-24 14:40:10.576539+08:00 [notice] <0.2398.0> Feature flags: checking nodes `rabbit@KL5` and `rabbit@KL6` compatibility...
2025-09-24 14:40:10.579022+08:00 [notice] <0.2398.0> Feature flags: nodes `rabbit@KL5` and `rabbit@KL6` are compatible
2025-09-24 14:40:10.582058+08:00 [notice] <0.44.0> Application mnesia exited with reason: stopped
2025-09-24 14:40:10.606314+08:00 [error] <0.2466.0> Mnesia(rabbit@KL5): ** ERROR ** mnesia_event got {inconsistent_database, starting_partitioned_network, rabbit@KL6}
2025-09-24 14:40:10.606314+08:00 [error] <0.2466.0>

有时可以在管理页面看到KL5集群节点并没有恢复,而是显示出现网络分区。同时消息队列中消息数量会变成主机、从机原本各自消息数量之和,如某队列集群故障前有消息12条,故障时收到消息6条,此时会显示18+12=30条。

使用命令行方式查看集群状态,也是相同的信息。

复制代码
[kylin@KL6 ~]$ rabbitmqctl cluster_status
rabbitmqctl cluster_status
Cluster status of node rabbit@KL6 ...
Basics
Cluster name: rabbit@KL6
Total CPU cores available cluster-wide: 2
Disk Nodes
rabbit@KL5
rabbit@KL6
Running Nodes
rabbit@KL6
............
这里很多状态信息,此处省略。
............
Network Partitions
Node rabbit@KL6 cannot communicate with rabbit@KL5
............
这里很多状态信息,此处省略。
............

此时两台主机均认为自己应该是集群主机,因此形成了两个集群网络,此时需要人工干预。一般此时应将KL5降为从机,保持KL6为主机。可以在KL5上使用rabbitmqctl stop_app、rabbitmqctl start_app重启动消息队列服务的方式完成。之后集群状态恢复,消息队列中消息数量恢复。

因此可以看到,在集群节点只有两台时,单节点故障后可以集群可以正常使用,但故障消除后,有些情况可以自动恢复,有些情况不能自动恢复。一般如果是主机间网络通讯故障造成的,一般会出现网络分区,不能自动恢复。如果是某台主机服务停止,通过重启动可以自动恢复。对于第一种情况,可以在rabbitmq.conf文件中配置cluster_partition_handling = autoheal来解决。

复制代码
[kylin@KL7 ~]$ vi /data/rabbitmq/etc/rabbitmq/rabbitmq.conf
cluster_partition_handling = autoheal
相关推荐
用户8307196840822 天前
RabbitMQ vs RocketMQ 事务大对决:一个在“裸奔”,一个在“开挂”?
后端·rabbitmq·rocketmq
初次攀爬者3 天前
RabbitMQ的消息模式和高级特性
后端·消息队列·rabbitmq
初次攀爬者5 天前
ZooKeeper 实现分布式锁的两种方式
分布式·后端·zookeeper
让我上个超影吧6 天前
消息队列——RabbitMQ(高级)
java·rabbitmq
塔中妖6 天前
Windows 安装 RabbitMQ 详细教程(含 Erlang 环境配置)
windows·rabbitmq·erlang
断手当码农6 天前
Redis 实现分布式锁的三种方式
数据库·redis·分布式
初次攀爬者6 天前
Redis分布式锁实现的三种方式-基于setnx,lua脚本和Redisson
redis·分布式·后端
业精于勤_荒于稀6 天前
物流订单系统99.99%可用性全链路容灾体系落地操作手册
分布式
Ronin3056 天前
信道管理模块和异步线程模块
开发语言·c++·rabbitmq·异步线程·信道管理
Asher05096 天前
Hadoop核心技术与实战指南
大数据·hadoop·分布式