二进制部署 Rabbitmq 3.8
场景
原有集群为 Rabbitmq 3.7.9
,因业务需要,要使用 Rabbitmq 3.8
的新队列属性 x-single-active-consumer
且不能影响原有集群的运转,但资源有限,需要使用不同的端口启动新集群,故使用二进制部署方式。
惯例,介绍下这个:
x-single-active-consumer
属性用于控制队列的行为,确保在任何给定时间只有一个消费者可以活跃地从队列中消费消息。
这个特性对于某些特定的用例非常有用,比如:
- 避免消息重复处理:在某些应用场景中,你可能希望确保每条消息只被处理一次,即使在消费者崩溃或重启的情况下也是如此。
- 提高消息处理的确定性:在需要严格顺序处理消息的场景中,
x-single-active-consumer
可以确保消息按照它们到达的顺序被单个消费者处理。 - 简化消费者实现:消费者实现可以简化,因为它们不需要处理消息的去重或确保消息的唯一性。
- 提高资源利用率:在某些情况下,如果有多个消费者竞争同一个队列中的消息,可能会导致资源浪费。使用
x-single-active-consumer
可以减少这种竞争。
当启用 x-single-active-consumer
属性时,RabbitMQ
会跟踪当前活跃的消费者,并确保只有当这个消费者断开连接时,其他消费者才能开始消费消息。
如果队列中没有消费者,消息将不会被消费,直到有一个新的消费者连接到队列。
这个属性的工作原理如下:
- 当一个消费者订阅到启用了
x-single-active-consumer
的队列时,如果队列中没有其他活跃的消费者,它将成为活跃消费者,并开始接收消息。 - 如果队列中已经有活跃的消费者,新的消费者将不会接收到任何消息,直到当前的活跃消费者断开连接。
- 当活跃消费者断开连接时,如果有其他消费者订阅了队列,其中一个消费者将自动成为新的活跃消费者,并开始接收消息。
部署
无特殊说明的,3
台机器做同样操作
准备工作
3
台机器,配置好 hosts
vim /etc/hosts
10.5.1.40 node1
10.5.1.41 node2
10.5.1.42 node3
创建目录,下载相关资源
mkdir -p /data/rabbitmq-3.8 && cd /data/rabbitmq-3.8
mkdir erlang_24.2
wget https://erlang.org/download/otp_src_24.2.tar.gz
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.34/rabbitmq-server-generic-unix-3.8.34.tar.xz
编译安装 erlang
初始环境
yum groupinstall -y "Development Tools"
yum install -y epel-release
yum install -y wxBase wxGTK3 wxGTK3-devel
yum install -y mesa-libGL-devel mesa-libGLU-devel
yum install -y ncurses-devel openssl-devel
yum install -y fop xsltproc unixODBC-devel
cd /usr/bin/
ln -sf wx-config-3.0 wx-config
编译安装
cd /data/rabbitmq-3.8/
tar xvf otp_src_24.2.tar.gz && cd otp_src_24.2
./configure --prefix=/data/rabbitmq-3.8/erlang_24.2
make && make install
部署 rabbitmq-3.8
编写 node1
机器配置文件和启动文件
# 解压
cd /data/rabbitmq-3.8/
tar xvf rabbitmq-server-generic-unix-3.8.34.tar.xz && cd rabbitmq_server-3.8.34
# 编写env配置文件
vim rabbitmq-env-3.8.conf
# 设置RabbitMQ节点的名称,用于集群中标识该节点
NODENAME=rabbitmq38@node1
# 设置RabbitMQ节点监听的AMQP协议默认端口
NODE_PORT=5673
# 定义Mnesia数据库的基础数据目录
RABBITMQ_MNESIA_BASE=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/base
# 定义Mnesia数据库的文件存储目录
RABBITMQ_MNESIA_DIR=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/base/mnesia
# 指定RabbitMQ的配置文件路径
RABBITMQ_CONFIG_FILE=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/rabbitmq-3.8.conf
# 定义RabbitMQ日志文件的存储目录
RABBITMQ_LOG_BASE=/var/log/rabbitmq-3.8
# 编写配置文件
vim rabbitmq-3.8.conf
# 设置RabbitMQ监听的TCP端口,默认情况下与NODE_PORT相同
listeners.tcp.default = 5673
# 设置RabbitMQ管理界面的HTTP API监听端口,用于访问管理控制台
management.listener.port = 15673
# 定义日志文件的存放目录
log.dir = /var/log/rabbitmq-3.8
# 定义日志文件的名称,包括节点名称和版本号
log.file = rabbitmq38@node1-3.8.log
# 编写启动文件
vim start-rabbitmq-3.8.sh
#!/bin/bash
# 将Erlang的bin目录添加到PATH环境变量中,确保可以从任何位置调用Erlang相关的命令
export PATH=/data/rabbitmq-3.8/erlang_24.2/bin:$PATH
# 设置RABBITMQ_CONF_ENV_FILE环境变量,指向RabbitMQ的环境配置文件
export RABBITMQ_CONF_ENV_FILE=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/rabbitmq-env-3.8.conf
# 启动RabbitMQ服务器,使用-detached选项使服务在后台运行
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmq-server -detached
# 创建相关目录、授权
mkdir -p /data/rabbitmq-3.8/rabbitmq_server-3.8.34/base
mkdir -p /var/log/rabbitmq-3.8
chown rabbitmq:rabbitmq /data/rabbitmq-3.8/rabbitmq_server-3.8.34/base
chown rabbitmq:rabbitmq /var/log/rabbitmq-3.8
chmod +x start-rabbitmq-3.8.sh
编写 node2
机器配置文件和启动文件
# 解压
cd /data/rabbitmq-3.8/
tar xvf rabbitmq-server-generic-unix-3.8.34.tar.xz && cd rabbitmq_server-3.8.34
# 编写env配置文件
vim rabbitmq-env-3.8.conf
# 设置RabbitMQ节点的名称,用于集群中标识该节点
NODENAME=rabbitmq38@node2
# 设置RabbitMQ节点监听的AMQP协议默认端口
NODE_PORT=5673
# 定义Mnesia数据库的基础数据目录
RABBITMQ_MNESIA_BASE=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/base
# 定义Mnesia数据库的文件存储目录
RABBITMQ_MNESIA_DIR=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/base/mnesia
# 指定RabbitMQ的配置文件路径
RABBITMQ_CONFIG_FILE=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/rabbitmq-3.8.conf
# 定义RabbitMQ日志文件的存储目录
RABBITMQ_LOG_BASE=/var/log/rabbitmq-3.8
# 编写配置文件
vim rabbitmq-3.8.conf
# 设置RabbitMQ监听的TCP端口,默认情况下与NODE_PORT相同
listeners.tcp.default = 5673
# 设置RabbitMQ管理界面的HTTP API监听端口,用于访问管理控制台
management.listener.port = 15673
# 定义日志文件的存放目录
log.dir = /var/log/rabbitmq-3.8
# 定义日志文件的名称,包括节点名称和版本号
log.file = rabbitmq38@node2-3.8.log
# 编写启动文件
vim start-rabbitmq-3.8.sh
#!/bin/bash
# 将Erlang的bin目录添加到PATH环境变量中,确保可以从任何位置调用Erlang相关的命令
export PATH=/data/rabbitmq-3.8/erlang_24.2/bin:$PATH
# 设置RABBITMQ_CONF_ENV_FILE环境变量,指向RabbitMQ的环境配置文件
export RABBITMQ_CONF_ENV_FILE=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/rabbitmq-env-3.8.conf
# 启动RabbitMQ服务器,使用-detached选项使服务在后台运行
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmq-server -detached
# 创建相关目录、授权
mkdir -p /data/rabbitmq-3.8/rabbitmq_server-3.8.34/base
mkdir -p /var/log/rabbitmq-3.8
chown rabbitmq:rabbitmq /data/rabbitmq-3.8/rabbitmq_server-3.8.34/base
chown rabbitmq:rabbitmq /var/log/rabbitmq-3.8
chmod +x start-rabbitmq-3.8.sh
编写 node3
机器配置文件和启动文件
# 解压
cd /data/rabbitmq-3.8/
tar xvf rabbitmq-server-generic-unix-3.8.34.tar.xz && cd rabbitmq_server-3.8.34
# 编写env配置文件
vim rabbitmq-env-3.8.conf
# 设置RabbitMQ节点的名称,用于集群中标识该节点
NODENAME=rabbitmq38@node3
# 设置RabbitMQ节点监听的AMQP协议默认端口
NODE_PORT=5673
# 定义Mnesia数据库的基础数据目录
RABBITMQ_MNESIA_BASE=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/base
# 定义Mnesia数据库的文件存储目录
RABBITMQ_MNESIA_DIR=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/base/mnesia
# 指定RabbitMQ的配置文件路径
RABBITMQ_CONFIG_FILE=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/rabbitmq-3.8.conf
# 定义RabbitMQ日志文件的存储目录
RABBITMQ_LOG_BASE=/var/log/rabbitmq-3.8
# 编写配置文件
vim rabbitmq-3.8.conf
# 设置RabbitMQ监听的TCP端口,默认情况下与NODE_PORT相同
listeners.tcp.default = 5673
# 设置RabbitMQ管理界面的HTTP API监听端口,用于访问管理控制台
management.listener.port = 15673
# 定义日志文件的存放目录
log.dir = /var/log/rabbitmq-3.8
# 定义日志文件的名称,包括节点名称和版本号
log.file = rabbitmq38@node3-3.8.log
# 编写启动文件
vim start-rabbitmq-3.8.sh
#!/bin/bash
# 将Erlang的bin目录添加到PATH环境变量中,确保可以从任何位置调用Erlang相关的命令
export PATH=/data/rabbitmq-3.8/erlang_24.2/bin:$PATH
# 设置RABBITMQ_CONF_ENV_FILE环境变量,指向RabbitMQ的环境配置文件
export RABBITMQ_CONF_ENV_FILE=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/rabbitmq-env-3.8.conf
# 启动RabbitMQ服务器,使用-detached选项使服务在后台运行
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmq-server -detached
# 创建相关目录、授权
mkdir -p /data/rabbitmq-3.8/rabbitmq_server-3.8.34/base
mkdir -p /var/log/rabbitmq-3.8
chown rabbitmq:rabbitmq /data/rabbitmq-3.8/rabbitmq_server-3.8.34/base
chown rabbitmq:rabbitmq /var/log/rabbitmq-3.8
chmod +x start-rabbitmq-3.8.sh
启动集群
每个节点都启动
# 3个节点一样操作
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/start-rabbitmq-3.8.sh
修改 erlang.cookie
文件
# 查看node1的,直接复制
cat /root/.erlang.cookie
KZFHWZQPIFEONDOOZUMY
# 把内容复制到node2和node3上
vim /root/.erlang.cookie
KZFHWZQPIFEONDOOZUMY
把 node2
和 node3
加入集群
# 两个节点一样操作,先停止服务
export PATH=/data/rabbitmq-3.8/erlang_24.2/bin:$PATH
export RABBITMQ_CONF_ENV_FILE=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/rabbitmq-env-3.8.conf
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmqctl stop
# 重新启动服务
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/start-rabbitmq-3.8.sh
# 把node2和node3加入集群
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmqctl stop_app
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmqctl reset
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmqctl join_cluster rabbitmq38@node1
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmqctl start_app
验证
集群配置
配置 web
页面、配置用户、配置镜像队列策略
# 随便一个节点上操作
# 配置环境变量
export PATH=/data/rabbitmq-3.8/erlang_24.2/bin:$PATH
export RABBITMQ_CONF_ENV_FILE=/data/rabbitmq-3.8/rabbitmq_server-3.8.34/rabbitmq-env-3.8.conf
# 创建用户
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmqctl add_user cloud 'cloud'
# 设置用户标签
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmqctl set_user_tags cloud administrator
# 设置权限
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmqctl set_permissions -p / cloud ".*" ".*" ".*"
# 检查用户和权限
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmqctl list_users
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmqctl list_permissions -p /
# 开启web管理插件
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmq-plugins enable rabbitmq_management
# 配置镜像队列策略
/data/rabbitmq-3.8/rabbitmq_server-3.8.34/sbin/rabbitmqctl set_policy ha-queues "^.*" '{"ha-mode":"exactly","ha-params":3,"ha-sync-mode":"automatic"}'
web
访问验证
打开浏览器访问 http://<node-ip>:15673
,使用 cloud
用户登录。检查集群状态和配置情况,确保 x-single-active-consumer
属性可用。
从图中可看到,集群部署完成、镜像队列策略配置完成、需要的队列属性 x-single-active-consumer
也有了,任务完成!
总结
通过以上步骤,我们成功在三台机器上部署了 RabbitMQ 3.8
集群,并启用了 x-single-active-consumer
特性。
这个特性确保在任何时间只有一个消费者活跃地消费消息,从而避免消息重复处理、提高处理确定性、简化消费者实现和提高资源利用率。
部署过程的要点
- 环境准备:确保三台机器配置一致,下载必要资源并安装依赖。
- 编译安装:安装
Erlang
和RabbitMQ
,配置相关文件。 - 集群配置:启动服务,同步
erlang.cookie
文件,将节点加入集群。 - 功能验证:通过
Web
界面检查集群状态和新特性配置。
这个部署方案不仅满足了业务需求,还确保了原有集群的正常运行,充分利用了有限的资源。