在CentOS 7上部署RabbitMQ集群
月月
・13 分钟阅读
RabbitMQ是支持AMQP,STOMP和其他通信技术的消息代理,在企业应用和现代微服务体系结构中,它被广泛应用于不同微服务之间的异步消息通道,本指南将介绍,如何在多个CentOS 7服务器上设置RabbitMQ集群以形成高可用性消息代理,在本教程中,一台服务器将充当主服务器,其他服务器将充当镜像服务器,以防主服务器变得不可用。
前提条件
- 在同一子网中,至少有两个新部署的CentOS 7实例,
- RabbitMQ随管理控制台一起安装在每个服务器上(请参见如何在CentOS 7上安装RabbitMQ )
- 有sudo权限的非管理员用户(请参见如何在Debian,CentOS和FreeBSD上使用sudo ),
配置防火墙
默认情况下,CentOS防火墙((firewalld
))不允许任何传入流量,为了让RabbitMQ可以用于网络内外的其他系统,并且允许我们访问管理控制台,我们必须首先打开一些端口。
RabbitMQ的web界面管理控制台默认在端口15672
上监听,因此,我们将指示firewalld中永久打开端口15672 。
sudo firewall-cmd --zone=public --add-port=15672/tcp --permanent
RabbitMQ节点需要能够互相通信,我们希望打开必要的端口,但是,只在内部网络上,我们不希望互联网上的任何人都能管理或直接与我们的服务器联系,以下命令假定我们的服务器位于192.168.0.100/24
子网上。
第一个服务是epmd
对等发现服务,它默认在端口4369
上监听。
sudo firewall-cmd --permanent --zone=public --add-rich-rule='
rule family="ipv4"
source address="192.168.0.100/24"
port protocol="tcp" port="4369" accept'
对于节间和25672
通信,RabbitMQ需要能够通过端口进行通信。
sudo firewall-cmd --permanent --zone=public --add-rich-rule='
rule family="ipv4"
source address="192.168.0.100/24"
port protocol="tcp" port="25672" accept'
CLI工具通过端口范围35672-35682
进行通信。
sudo firewall-cmd --permanent --zone=public --add-rich-rule='
rule family="ipv4"
source address="192.168.0.100/24"
port protocol="tcp" port="35672-35682" accept'
如果应用程序需要AMQP协议,你还需要打开端口5671
和5672
,
sudo firewall-cmd --permanent --zone=public --add-rich-rule='
rule family="ipv4"
source address="192.168.0.100/24"
port protocol="tcp" port="5672" accept'
sudo firewall-cmd --permanent --zone=public --add-rich-rule='
rule family="ipv4"
source address="192.168.0.100/24"
port protocol="tcp" port="5671" accept'
现在firewalld
已经配置好了,我们需要指示它重新加载配置。
sudo firewall-cmd --reload
对所有服务器重复此部分中的步骤。
安装rabbitmqadmin
管理插件带有一个名为rabbitmqadmin
的python工具,一旦管理插件启用,就可以轻松安装在系统上。
sudo wget http://localhost:15672/cli/rabbitmqadmin
sudo mv rabbitmqadmin /usr/local/bin/
sudo chmod +x /usr/local/bin/rabbitmqadmin
配置DNS
使用群集时,必须使用服务器的主机名来标识服务器,默认情况下,服务器没有分配DNS记录,连接将失败,要快速解决这个问题,使用你喜欢的编辑器将主主机名和镜像主机名添加到/etc/hosts
文件中。
例如主文件的主机可能如下所示,注意最后两条记录,这些记录允许服务器通过它主机名来标识彼此,请务必将IP地址更改为你自己的。
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 guest
::1 guest
127.0.0.1 YOUR_MASTER_SERVER_HOST_NAME
::1 YOUR_MASTER_SERVER_HOST_NAME
192.168.0.101 YOUR_MASTER_SERVER_HOST_NAME
192.168.0.102 YOUR_MIRROR_SERVER_HOST_NAME
群集节点
允许节点加入其他节点的一个重要条件是,所有节点的Erlang cookie都是相同的,默认情况下,每个节点都会分配一个惟一的Erlang cookie,因此你必须在所有节点上重新配置它。
以下命令将Erlang设置为"WE<3COOKIES
",但是,你可以随意更改它,在所有服务器上执行这个操作。
sudo sh -c"echo 'WE<3COOKIES' > /var/lib/rabbitmq/.erlang.cookie"
在所有服务器上重新启动RabbitMQ,以确保正确地重新加载了Erlang cookie 。
sudo systemctl restart rabbitmq-server.service
在除主服务器外的所有服务器上执行以下命令,这将让节点加入主服务器,并且形成集群。
sudo rabbitmqctl stop_app
sudo rabbitmqctl join_cluster"rabbit@<YOUR_MASTER_SERVER_HOST_NAME>"
sudo rabbitmqctl start_app
通过运行以下命令验证节点是否已加入群集。
sudo rabbitmqctl cluster_status
所有节点都将出现在输出的nodes
和running_nodes
部分中,从现在开始,你不再需要在每个服务器上重复步骤,配置将自动镜像其他节点。
创建高可用性策略
现在我们拥有了RabbitMQ节点集群,我们可以通过设置新的策略来实现高可用性队列和交换,这个策略可以通过RabbitMQ管理控制台添加或者使用命令行接口。
sudo rabbitmqctl set_policy -p"/" --priority 1 --apply-to"all" ha".*" '{"ha-mode":"exactly","ha-params": 2,"ha-sync-mode":"automatic"}'
下面的列表将解释命令的每个部分的含义。
-p"/"
:在"/"
vhost (安装后,默认)上使用此策略--priority 1
:应用策略的顺序--apply-to"all"
:可以是"queues"
"exchanges"
或"all"
ha
:我们给策略的名称".*"
:用于决定应用该策略的队列或交换的正则表达式,".*"
将匹配任何'{"ha-mode":"exactly","ha-params": 2,"ha-sync-mode":"automatic"}'
:策略的JSON表示形式,
简单而言,只要有至少2个节点正在运行,此策略将确保队列或交换中始终有2个数据副本,如果有更多的节点,可以增加ha-params
的值,建议使用仲裁,(N/2 +1
)节点,拥有更多的数据副本会导致磁盘,i/o和网络使用率的提高,从而导致性能下降。
如果希望将数据镜像到集群中的所有节点,可以使用以下JSON文档。
'{"ha-mode":"all","ha-sync-mode":"automatic"}'
如果你希望仅将数据镜像到特定节点,请执行以下操作: node-1
和node-2
),你可以使用以下命令。
'{"ha-mode":"nodes","ha-params" :["rabbit@node-1","rabbit@node-2"],"ha-sync-mode":"automatic"}'
可以更改正则表达式,为不同的队列分配不同的策略,假设我们有以下三个节点:
- rabbit@master
- rabbit@client-ha
- rabbit@product-ha
然后,我们可以创建两个策略,将以"客户端"开头的队列镜像到rabbit@client-ha node,并将它名称从"product"镜像到rabbit@product-ha 节点。
sudo rabbitmqctl set_policy -p"/" --priority 1 --apply-to"queues" ha-client"client.*" '{"ha-mode":"nodes","ha-params": ["rabbit@master","rabbit@client-ha"],"ha-sync-mode":"automatic"}
sudo rabbitmqctl set_policy -p"/" --priority 1 --apply-to"queues" ha-product"product.*" '{"ha-mode":"nodes","ha-params": ["rabbit@master","rabbit@product-ha"],"ha-sync-mode":"automatic"}
这里有一个小注释:RabbitMQ中的独占队列永远不会被镜像或持久,即使此策略与这些队列匹配也是如此。客户端断开连接后,独占队列会自动销毁,因此无法将其复制到其他服务器,如果服务器失败,客户端将断开连接,队列将自动销毁,镜像实例也会被销毁。
测试设定
为了测试集群设置,我们可以通过管理控制台使用命令行接口创建一个新的队列。
sudo rabbitmqadmin declare queue --vhost"/" name=my-ha-queue durable=true
这将在默认/
vhost上创建一个持久队列,名称为my-ha-queue
。
运行以下命令,并且在输出中验证队列是否分配了ha策略,以及主节点和镜像节点上有没有PID 。
sudo rabbitmqctl list_queues name policy state pid slave_pids
现在我们可以从主节点发布消息到队列,并在主节点上停止RabbitMQ 。
sudo rabbitmqadmin -u user_name -p password publish routing_key=my-ha-queue payload="hello world"
sudo systemctl rabbitmqctl shutdown
现在通过连接镜像节点来恢复它。
sudo rabbitmqadmin -H MIRROR_NODE_IP_OR_DNS -u user_name -p password get queue=my-ha-queue
最后,我们可以重启主节点 。
sudo systemctl start rabbitmq-server.service
删除来宾用户
如上所述,RabbitMQ会自动创建一个带有默认来宾密码的guest用户,将此默认用户留在公开的系统上是不好的做法。
sudo rabbitmqctl delete_user guest