在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协议,你还需要打开端口56715672


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

所有节点都将出现在输出的nodesrunning_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-1node-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

月月 profile image