RabbitMQ的安装集群、仲裁队列配置

1 RabbitMQ集群简介

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

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

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

RabbitMQ的集群部署有两种模式:普通集群是一种分布式集群,将队列分散到集群的各个节点,提高整个集群的并发能力。镜像集群在普通集群的基础上,添加了主从备份功能,又称为主从复制集群,提高集群的数据可用性。

镜像集群虽然支持主从复制,但主从同步并不是强一致的,某些情况下可能有数据丢失的风险。因此在RabbitMQ的3.8版本以后,推出了新的功能:使用仲裁队列来代替镜像集群,底层采用Raft协议确保主从的数据一致性。请求仍然都是由主节点进行操作,然后同步到从节点中。但是对于任何节点来说,既可能是某个仲裁队列的主节点,也可能是其它仲裁队列的从节点。因此也具有分散节点压力,提高并发访问的特点。另外如果主节点挂了,其中的某个从节点就会变成主节点,并在其它节点上尽可能创建出新的主节点,保障主从数量一致。一个仲裁队列的默认数量是5,即一个主节点,4个副本节点,如果集群中节点数量少于5,比如我们搭建了3个节点的集群,那么创建的仲裁队列就是1主2副本。当然如果集群中的节点数大于5个的话,那么就只会在5个节点中创建出1主4副本。

本例即是通过普通集群加仲裁队列来实现RabbitMQ的高可用。

2 安装配置规划

配置项 主机一 主机二 主机三
IP地址 10.10.1.41 10.10.1.42 10.10.1.43
主机名称 KL1 KL2 KL3
配置用户 kylin kylin kylin
安装文件目录 /home/kylin/Install /home/kylin/Install /home/kylin/Install
消息队列目录 /data/rabbitmq /data/rabbitmq /data/rabbitmq
相关端口 使用默认值 使用默认值 使用默认值
MQ测试用户 test/password
MQ虚拟主机 test

3 安装RabbitMQ

3.1 安装版本说明

RabbitMQ仅3.8及以上版本支持仲裁队列,因此本例选择最新版本的RabbitMQ4.1.4版。根据官方网站上RabbitMQ与Erlang的版本兼容性矩阵,Erlang版本选择27.x中最新的27.3.4.3。

银河麒麟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@KL1:~$ 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@KL1:~/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@KL1:~/Install$ tar -zxf ncurses-6.5.tar.gz
kylin@KL1:~/Install$ cd ncurses-6.5/
kylin@KL1:~/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@KL1:~/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@KL1:~/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@KL1:~/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@KL1:~/Install$ cd openssl-OpenSSL_1_1_1w/

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

复制代码
kylin@KL1:~/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@KL1:~/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@KL1:~/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 KL1
[root@localhost ~]# logout

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

复制代码
[kylin@KL1 ~]$ 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@KL1 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_27.3.4.3.tar.gz,放置到安装目录。解压缩安装包后进入解压后的目录,执行configure命令。

复制代码
kylin@KL1:~/Install$ tar -zxf otp_src_27.3.4.3.tar.gz
kylin@KL1:~/Install$ cd otp_src_27.3.4.3/
kylin@KL1:~/Install/otp_src_27.3.4.3$ ./configure
=== Running configure in /home/kylin/Install/otp_src_27.3.4.3/erts ===
./configure --disable-option-checking --cache-file=/dev/null --srcdir="/home/kylin/Install/otp_src_27.3.4.3/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
checking for gcc... gcc
............
这里很多提示信息,此处省略。
............
        Please check that wx-config is in path, the directory
        where wxWidgets libraries are installed (returned by
        'wx-config --libs' or 'wx-config --static --libs' command)
        is in LD_LIBRARY_PATH or equivalent variable and
        wxWidgets version is 3.0.2 or above.
*********************************************************************

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

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

复制代码
kylin@KL1:~/Install/otp_src_27.3.4.3$ make
 MAKE   depend
make[1]: 进入目录"/home/kylin/Install/otp_src_27.3.4.3/erts/emulator"
 MAKE   generate
make[2]: 进入目录"/home/kylin/Install/otp_src_27.3.4.3/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_27.3.4.3/bin/start.script
 GEN    /home/kylin/Install/otp_src_27.3.4.3/bin/start_sasl.script
 GEN    /home/kylin/Install/otp_src_27.3.4.3/bin/start_clean.script
make[2]: "/home/kylin/Install/otp_src_27.3.4.3/bin/no_dot_erlang.script"已是最新。
make[2]: 离开目录"/home/kylin/Install/otp_src_27.3.4.3/erts/start_scripts"
make[1]: 离开目录"/home/kylin/Install/otp_src_27.3.4.3/erts"

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

复制代码
kylin@KL1:~/Install/otp_src_27.3.4.3$ sudo make install
MAKE   erl_interface_build
make[1]: 进入目录"/home/kylin/Install/otp_src_27.3.4.3/lib/erl_interface"
=== Entering application erl_interface
make[2]: 进入目录"/home/kylin/Install/otp_src_27.3.4.3/lib/erl_interface/src"
 MAKE   opt
make[3]: 进入目录"/home/kylin/Install/otp_src_27.3.4.3/lib/erl_interface/src"
make[3]: 对"opt"无需做任何事。
............
这里很多提示信息,此处省略。
............
ln -s ../lib/erlang/bin/run_erl run_erl
ln -s ../lib/erlang/bin/to_erl to_erl
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

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

复制代码
kylin@KL1:~$ erl
Erlang/OTP 27 [erts-15.2.7.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] 
Eshell V15.2.7.2 (press Ctrl+G to abort, type help(). for help)
1> crypto:start().
ok
2> halt().

3.5 安装RabbitMQ

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

复制代码
kylin@KL1:~/Install$ tar -xf rabbitmq-server-generic-unix-4.1.4.tar.xz
kylin@KL1:~/Install$ mv rabbitmq_server-4.1.4 /data/rabbitmq

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

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

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

复制代码
kylin@KL1:~$ rabbitmq-server -detached
kylin@KL1:/data/rabbitmq$ rabbitmqctl status
Status of node rabbit@KL1 ...
Runtime
OS PID: 616311
............
此处有很多状态信息,此处忽略。
............
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@KL1:/data/rabbitmq$ rabbitmqctl start_app
Starting node rabbit@KL1 ...
kylin@KL1:/data/rabbitmq$ rabbitmq-plugins enable rabbitmq_management
Enabling plugins on node rabbit@KL1:
rabbitmq_management
The following plugins have been configured:
  rabbitmq_management
  rabbitmq_management_agent
  rabbitmq_web_dispatch
Applying plugin configuration to rabbit@KL1...
The following plugins have been enabled:
  rabbitmq_management
  rabbitmq_management_agent
  rabbitmq_web_dispatch
started 3 plugins.
kylin@KL1:~$ rabbitmqctl status
Status of node rabbit@KL1 ...
Runtime
............
此处有很多状态信息,此处忽略。
............
Interface: [::], port: 15672, protocol: http, purpose: HTTP API
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

3.6 注册RabbitMQ为服务

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

复制代码
kylin@KL1 ~$ 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@KL1 ~$ sudo systemctl daemon-reload
kylin@KL1 ~$ sudo systemctl enable rabbitmq
Created symlink /etc/systemd/system/multi-user.target.wants/rabbitmq.service → /etc/systemd/system/rabbitmq.service.

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

复制代码
kylin@KL1 ~$ ps -AL|grep beam
   2212    2212 ?        00:00:00 beam.smp
kylin@KL1 ~$ kill 2212
kylin@KL1 ~$ sudo systemctl start rabbitmq
kylin@KL1 ~$ 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@KL1~$ sudo vi /etc/hosts
127.0.0.1       localhost
10.10.1.41      KL1
10.10.1.42      KL2
10.10.1.43      KL3

4.2 开放防火墙端口

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

复制代码
[kylin@KL1 ~]$ sudo firewall-cmd --add-port=4369/tcp --permanent
success
[kylin@KL1 ~]$ sudo firewall-cmd --add-port=5671-5672/tcp --permanent
success
[kylin@KL1 ~]$ sudo firewall-cmd --add-port=15672/tcp --permanent
success
[kylin@KL1 ~]$ sudo firewall-cmd --add-port=25672/tcp --permanent
success
[kylin@KL1 ~]$ sudo firewall-cmd --add-port=35672-35682/tcp --permanent
success
[kylin@KL1 ~]$ sudo firewall-cmd --reload
success
[kylin@KL1 ~]$ 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@KL1:~$ scp .erlang.cookie kylin@KL2:/home/kylin
kylin@KL2's password:
.erlang.cookie                                              100%   20     7.8KB/s   00:00

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

复制代码
[kylin@KL1 ~]$ 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@KL2:~$ rabbitmqctl stop_app
Stopping rabbit application on node rabbit@KL2 ...

kylin@KL2:~$ rabbitmqctl join_cluster rabbit@KL1
Clustering node rabbit@KL2 with rabbit@KL1

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

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

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

4.5 增加测试用户

正常情况下在本机可以使用默认用户guest登录管理页面,但guest用户默认被禁止在本机以外登录管理页面,此时可以先用命令行方式增加虚拟主机、增加用户、设置角色、设置权限,在通过新建的用户远程登录管理页面。

复制代码
kylin@KL1:~$ rabbitmqctl add_vhost /test
Adding vhost "/test" ...
kylin@KL1:~$ rabbitmqctl add_user test password
Adding user "test" ...
kylin@KL1:~$ rabbitmqctl set_user_tags test administrator
Setting tags for user "test" to [administrator] ...
kylin@KL1:~$ rabbitmqctl set_permissions -p /test test ".*" ".*" ".*"
Setting permissions for user "test" in vhost "/test" ...

4.6 创建仲裁队列

使用浏览器打开主机的配置页面,创建需要的交换机和消息队列等,在创建消息队列时选择quorum类型。

如果是使用程序创建消息队列,在创建方法中的arguments参数中,设置"x-queue-type"值为"quorum"。

5 集群切换测试

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

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

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

在KL1故障状态下,向消息队列dataQueue又发送了6条数据,现在KL2显示共有16条数据。

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

复制代码
kylin@KL3:~$ tail -f /data/rabbitmq/var/log/rabbitmq/rabbit@KL3.log
2025-09-29 11:47:38.441999+08:00 [notice] <0.15253.0> queue 'alarmQueue' in vhost '/test': candidate -> leader in term: 2 machine version: 7, last applied 2
2025-09-29 11:47:38.625921+08:00 [notice] <0.15237.0> queue 'commandQueue' in vhost '/test': candidate -> leader in term: 2 machine version: 7, last applied 5
2025-09-29 11:47:38.836939+08:00 [notice] <0.15245.0> queue 'answerQueue' in vhost '/test': candidate -> leader in term: 2 machine version: 7, last applied 2
2025-09-29 11:47:39.035406+08:00 [notice] <0.15261.0> queue 'dataQueue' in vhost '/test': candidate -> leader in term: 2 machine version: 7, last applied 14
2025-09-29 11:47:39.085129+08:00 [notice] <0.15269.0> queue 'faultQueue' in vhost '/test': candidate -> leader in term: 2 machine version: 7, last applied 2
2025-09-29 11:48:34.480926+08:00 [error] <0.611.0> ** Node rabbit@KL1 not responding **
2025-09-29 11:48:34.480926+08:00 [error] <0.611.0> ** Removing (timedout) connection **
2025-09-29 11:48:34.480926+08:00 [error] <0.611.0>
2025-09-29 11:48:34.481448+08:00 [info] <0.1310.0> rabbit on node rabbit@KL1 down
2025-09-29 11:48:34.481730+08:00 [warning] <0.18251.0> Management delegate query returned errors:
2025-09-29 11:48:34.481730+08:00 [warning] <0.18251.0> [{<31743.492.0>,{exit,{nodedown,rabbit@KL1},[]}}]
2025-09-29 11:48:34.482387+08:00 [warning] <0.1480.0> Management delegate query returned errors:
2025-09-29 11:48:34.482387+08:00 [warning] <0.1480.0> [{<31743.492.0>,{exit,{nodedown,rabbit@KL1},[]}}]
2025-09-29 11:48:41.489553+08:00 [info] <0.1310.0> node rabbit@KL1 down: net_tick_timeout

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

复制代码
kylin@KL3:~$ rabbitmqctl cluster_status
Cluster status of node rabbit@KL3 ...
Basics
Cluster name: rabbit@KL3
Total CPU cores available cluster-wide: 2
Cluster Tags
(none)
Disk Nodes
rabbit@KL1
rabbit@KL2
rabbit@KL3
Running Nodes
rabbit@KL2
rabbit@KL3............
这里很多状态信息,此处省略。
............

此时恢复虚拟机,将KL1主机恢复并接入。此时发生了集群网络分区,即KL1处于一个分区,KL2、KL3处于一个分区。

此时查看队列,发现共有26条,实际上包含KL1所在分区在KL1断网前收到的10条消息,KL2、KL3所在分区在KL1断网前收到的10条消息和KL1断网后收到的6条消息,其中KL1断网前的10条消息被重复计算了。

可以在KL1上使用rabbitmqctl stop_app、rabbitmqctl start_app重启动消息队列服务的方式完成分区消除。之后集群状态恢复,消息队列中消息数量恢复为16条。

在rabbitmq.conf文件中配置cluster_partition_handling = autoheal参数,可以使得集群恢复时,自动解决网络分区问题。

复制代码
kylin@KL1:~$ vi /data/rabbitmq/etc/rabbitmq/rabbitmq.conf
cluster_partition_handling = autoheal

使用autoheal配置的集群,在集群中主机恢复后,可以消除网络分区,自动恢复集群。

复制代码
2025-09-29 15:03:26.331319+08:00 [error] <0.257.0> ** Node rabbit@KL1 not responding **
2025-09-29 15:03:26.331319+08:00 [error] <0.257.0> ** Removing (timedout) connection **
2025-09-29 15:03:26.331319+08:00 [error] <0.257.0>
2025-09-29 15:03:26.331567+08:00 [info] <0.491.0> rabbit on node rabbit@KL1 down
2025-09-29 15:03:26.331699+08:00 [warning] <0.1045.0> Management delegate query returned errors:
2025-09-29 15:03:26.331699+08:00 [warning] <0.1045.0> [{<24597.678.0>,{exit,{nodedown,rabbit@KL1},[]}}]
2025-09-29 15:03:26.331785+08:00 [warning] <0.741.0> Management delegate query returned errors:
2025-09-29 15:03:26.331785+08:00 [warning] <0.741.0> [{<24597.678.0>,{exit,{nodedown,rabbit@KL1},[]}}]
2025-09-29 15:03:33.343042+08:00 [info] <0.491.0> node rabbit@KL1 down: net_tick_timeout
2025-09-29 15:03:54.352322+08:00 [info] <0.491.0> node rabbit@KL1 up
2025-09-29 15:03:54.395179+08:00 [info] <0.491.0> Autoheal: I am the winner, waiting for [rabbit@KL1] to stop
2025-09-29 15:04:55.798338+08:00 [info] <0.491.0> rabbit on node rabbit@KL1 up
2025-09-29 15:04:56.269645+08:00 [info] <0.556.0> queue 'answerQueue' in vhost '/test': granting vote for {'/test_answerQueue',rabbit@KL1} with last {index, term} {8,7} for term 8 previous term was 7
2025-09-29 15:04:56.286039+08:00 [info] <0.556.0> queue 'answerQueue' in vhost '/test': detected a new leader {'/test_answerQueue',rabbit@KL1} in term 8

6 参考文献

https://www.rabbitmq.com/docs/which-erlang

https://www.rabbitmq.com/docs/4.0

https://rabbitmq.cn/docs/

https://www.cnblogs.com/studyjobs/p/17744247.html

https://github.com/rabbitmq/rabbitmq-server/blob/v3.8.9/docs/rabbitmq.conf.example

相关推荐
Z_z在努力5 小时前
【rabbitmq】RabbitMQ 全面详解:从核心概念到高级应用
分布式·rabbitmq
漫谈网络1 天前
RabbitMQ核心机制解析
分布式·rabbitmq
ApachePulsar1 天前
Apache Pulsar vs. RabbitMQ:差异与比较
分布式·rabbitmq·apache
Z_z在努力1 天前
【rabbitmq 高级特性】RabbitMQ 延迟队列全面解析
分布式·rabbitmq
sg_knight2 天前
Spring Cloud与RabbitMQ深度集成:从入门到生产级实战
java·spring boot·spring·spring cloud·消息队列·rabbitmq·stream
IT机器猫2 天前
RabbitMQ
java·rabbitmq·java-rabbitmq
熊文豪2 天前
Windows安装RabbitMQ保姆级教程
windows·分布式·rabbitmq·安装rabbitmq
勇往直前plus2 天前
CentOS 7 环境下 RabbitMQ 的部署与 Web 管理界面基本使用指南
前端·docker·centos·rabbitmq
一叶飘零_sweeeet3 天前
从 0 到 1 搭建实时数据看板:RabbitMQ+WebSocket 实战指南
java·websocket·rabbitmq·数据看板