简述
RabbitMQ是流行的开源消息队列系统,本身已经具备了较强的并发处理速度及运行稳定性,然而在大规模的实际应用中,往往还需要使用集群配置来保证系统中消息通信部分的高可用性,并发处理性能及异常恢复能力。这里将介绍一种实用的消息集群架构,以及一种能够快速、高效、可靠地部署并配置消息集群的方式,通过这种方法,我们可以在系统部署时仅需短短几分钟就能完成规模化的消息集群架设,极大地提高了工作效率和部署成功率。
集群结构设计
RabbitMQ 已经支持与 Erlang 集成的 active/active cluster 方案,但是为了实现集群的高可用及自动化管理,我们还需要一个集群管理工具,来负责监控各节点消息服务的运行状态,以及在发现异常时自动执行一些预订的恢复动作,从而增强集群的容错恢复能力和持续服务能力。我们这里选择的是 Pacemaker 加 RabbitMQ 的集成方式。
集群结构如下图所示,RabbitMQ clustering 部分提供消息集群内部心跳检查及数据管理和同步功能,Pacemaker 则负责监控 RabbitMQ 各节点的服务状态及异常恢复,保证集群正常运行。
图 1.RabbitMQ 集群结构
部署准备工作
准备工作主要分为如下几个步骤:
- 配置系统软件源,需要包括 Erlang,RabbitMQ,Pacemaker 及相关的依赖包。
本文采用的各主要软件及版本包括:rhel6.5,rabbitmq3.4.4,erlang17.0,pacemaker1.1.12,corosync2.3.4,可以根据实际情况增减所需依赖。 - 这里使用 Chef 实现自动化安装,需要一台配置好的 Chef Server,详细介绍请参考 Chef Server安装配置。
- 下载需要的社区 Cookbook:
如果你的软件源里已经包含了 Erlang 相关 package,可以不用下载 Erlang Cookbook,只需修改RabbitMQ里的 Erlang 安装方式为本地安装就可以,本文采用本地安装方式,需要修改 RabbitMQ Cookbook 中以下文件:
- 修改 metadata.rb,去除 RabbitMQ Cookbook 的 Erlang 依赖
1 |
#depends 'erlang'
|
- 修改 recipe/default.rb 为本地安装
1 2 |
#include_recipe 'erlang'
package 'erlang'
|
如果系统启用了 iptables,还需要下载使用 iptables Cookbook 来开放相应端口。
自动安装流程
为实现本文使用的消息集群结构,需要在所有消息节点上分别搭建RabbitMQ的集群与 Pacemaker 的集群,设计完成的自动脚本安装配置过程如下:
- 添加所有节点的 ip hostname 映射至/etc/hosts,用作RabbitMQ cluster 之间通信
- 安装RabbitMQ,设置统一的 erlang cookie,通过配置文件 (/etc/rabbitmq/rabbitmq.config) 来创建 cluster,并开放相应端口
- 4369 (epmd), 25672 (Erlang distribution)
- 5672, 5671 (AMQP 0-9-1 without and with TLS)
- 15672 (if management plugin is enabled)
- 61613, 61614 (if STOMP is enabled)
- 1883, 8883 (if MQTT is enabled)
- 安装 Pacemaker,并开放相应端口
- 5405 (corosync)
- 创建新的RabbitMQ账户供用户使用。从 rabbitmq3.3.0 版本开始,guest 账户默认不支持远程访问,需另建带相应权限的远程访问帐号。
- 创建 pacemaker rabbitmq resource,并 clone 至所有节点。
注意:上述 1、2、3 步骤需要在所有节点执行,4、5 步只需在任一台 cluster 节点上执行一次就可以对整个集群生效。
详细实现
将所有下载的 Cookbook 放至相同目录下,按以下步骤创建并修改新的 rabbitmq-ha cookbook,实现自动安装流程:
- 在 Chef Server 上使用 knife 命令创建 rabbitmq-ha cookbook
1 knife cookbook create rabbitmq-ha
- 进入创建的 rabbitmq-ha cookbook 目录,修改文件 metadata.rb,增加以下 Cookbook 依赖
1 2 3 depends iptables
depends rabbitmq
depends pacemaker
- 在 rabbitmq-ha cookbook 中添加 iptables 端口模板文件 templates/default/port.erb
1 2 3 4 5 -A FWR -p tcp --dports 5672 -j ACCEPT
-A FWR -p tcp --dports 4369 -j ACCEPT
-A FWR -p tcp --dports 25672 -j ACCEPT
-A FWR -p udp --dports 5405 -j ACCEPT
-A FWR -p udp --sports 5405 -j ACCEPT
- 添加安装脚本 recipe/ha-install.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 注册端口
iptables_rule 'port'
# 添加 ip hostname 映射
execute 'add qpd hostnames to /etc/hosts' do
command <<-EOF
echo "# Hosts of rabbitmq nodes" >> /etc/hosts
echo "192.168.1.10 rab001" >> /etc/hosts
echo "192.168.1.11 rab002" >> /etc/hosts
EOF
end
# 安装 rabbitmq
include_recipe 'rabbitmq'
# 安装 pacemaker
include_recipe 'pacemaker'
- 添加集群配置脚本 recipe/ha-setup.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # 创建 rabbitmq 用户
rabbitmq_user 'rabbituser' do
password 'password'
action :add
end
# 设置权限
rabbitmq_user 'rabbituser' do
vhost '/'
permissions '.* .* .*'
action :set_permissions
end
# 创建 clone 资源
pacemaker_clone 'rabbitmq' do
name "RABBITMQ"
agent "ocf:rabbitmq:rabbitmq-server"
params { "nodename" => "rabbit@`hostname -s`", "config_file" => "/etc/rabbitmq/rabbitmq" }
op {'monitor' => { 'interval' => '10s', 'timeout' => '30s' } }
action :create
end
- 在 Cookbook 同级目录创建 environment 文件:rabbit-ha-env.json,并配置RabbitMQ相关参数
1 2 3 4 5 6 7 8 9 10 11 {
"name": "rabbit-ha-env",
"json_class": "Chef::Environment",
"chef_type": "environment",
"override_attributes": {
"rabbitmq": {
"cluster": true,
"cluster_disk_nodes": ["rabbit@rab001", "rabbit@rab002"]
}
}
}
安装
安装步骤如下:
- 进入存放所有 Cookbook 的目录,上传所有 Cookbook 至 Chef Server
1 knife cookbook upload -a -o .
也可以分别单独上传。
1 knife cookbook upload rabbitmq-ha -o .
- 上传 environment 文件
1 knife environment from file rabbit-ha-env.json
- 顺序执行安装命令,等待前一个节点安装完成后再执行下个节点
1 2 3 4 knife bootstrap 192.168.1.10 -x root -P ×××××× -r
"recipe[rabbitmq-ha::ha-install]" -E rabbit-ha-env
knife bootstrap 192.168.1.11 -x root -P ×××××× -r "recipe[rabbitmq-ha::ha-install],
recipe[rabbitmq-ha::ha-setup]" -E rabbit-ha-env
验证
安装成功后,SSH 登录任意一个 RabbitMQ 节点检查安装状态
- 检查 RabbitMQ 集群状态,所有节点处于 running list 中:
1 |
rabbitmqctl cluster_status
|
- 检查 Pacemaker 集群状态,所有节点 online 并且 started
1 |
pcs status
|
集群管理
配置完成后 Pacemaker 集群会自动对各节点 RabbitMQ 的服务运行状态进行监控管理,RabbitMQ 集群负责对外提供消息服务。以下是集群常用管理命令:
- 通过 Pacemaker 来管理各节点 RabbitMQ 服务运行状态
- 停止监控节点并停止 Rabbit 服务:
1 crm_standby -U rab001 -v on
- 重新开启监控开启 Rabbit 服务:
1 crm_standby -U rab001 -v off
- 配置好 resource 后 Pacemaker 已经接管了 RabbitMQ 服务,启停 Pacemaker 服务同样会导致 RabbitMQ 服务的启动和停止
1 service pacemaker restart
- RabbitMQ 集群管理
- 查看用户列表
1 |
rabbitmqctl list_users
|
- 查看用户权限
1 |
rabbitmqctl list_user_permissions rabbituser
|
- 查看 HA 策略
1 |
rabbitmqctl list_policies
|
结束语
在大规模的企业应用系统中,负责消息收发的模块往往承担着非常重要的中间角色和非常庞大的处理压力,所以在系统的设计阶段就必须对可能出现的业务瓶颈作出合理的预判,并采取相应的架构设计来适当应对。在所有系统的实际使用阶段,拥有快速可靠地部署稳定、可用、不间断服务的能力,以及适当的自我恢复,无疑是可以影响产品成功与否的关键性因素,所以必须审慎对待