好的,RabbitMQ 的镜像模式是实现高可用性的核心方式。它通过将队列的消息和状态复制到集群中的多个节点上,确保即使某个节点故障,队列仍然可用。
下面我将详细讲解如何配置 RabbitMQ 镜像模式,包括前提条件、配置方法和策略说明。
镜像队列就是一个主队列(Master)和若干个镜像队列(Mirror)的组合。所有操作(发布消息、消费消息、确认消息)首先在主队列上执行,然后 RabbitMQ 会将操作同步到所有镜像。
- 主队列:处理所有读写操作,通常位于最初声明队列的节点上。
- 镜像队列:是主队列的副本,只做备份和故障转移用。
- 客户端连接:无论连接到哪个节点,最终都是与主队列交互。
当主队列所在节点故障时,**最老**的镜像队列(即最先加入的)会自动被提升为新的主队列,从而实现高可用。
镜像模式是建立在普通集群之上的,所以你必须先有一个正常运行的 RabbitMQ 集群。
1. 配置 Hosts 文件
确保所有节点之间可以通过主机名相互解析。在每个节点的 /etc/hosts
文件中添加类似记录:
192.168.1.10 node1.rabbit
192.168.1.11 node2.rabbit
192.168.1.12 node3.rabbit
2. 同步 Erlang Cookie
Erlang Cookie 是节点间通信的密钥。必须保证集群内所有节点的 Cookie 一致。
- Cookie 文件通常位于 /var/lib/rabbitmq/.erlang.cookie
或 $HOME/.erlang.cookie
。
- 选择一个节点的 Cookie,复制到其他节点,并确保**文件权限是 400**。
chmod 400 /var/lib/rabbitmq/.erlang.cookie
chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie
3. 组建集群
在 node2
和 node3
上执行,将它们加入到 node1
的集群中。
# 在 node2 上执行
rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@node1 # 使用 node1 的主机名
rabbitmqctl start_app
# 在 node3 上执行
rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@node1
rabbitmqctl start_app
4. 验证集群状态
在任何节点上执行:
rabbitmqctl cluster_status
你应该能看到三个节点都已列出。
RabbitMQ 通过 策略(Policy) 来配置镜像模式。策略会匹配队列名称,并对匹配上的队列应用镜像规则。
以下命令创建了一个名为 ha-all
的策略,它将所有名称以 ha.
开头的队列镜像到集群中的所有节点。
rabbitmqctl set_policy ha-all "^ha\." '{"ha-mode":"all"}'
ha-all
:策略的名称,可以自定义。"^ha\."
:正则表达式,匹配所有以 ha.
开头的队列名称。'{"ha-mode":"all"}'
:镜像参数,ha-mode: all
表示镜像到所有节点。http://your-server:15672
)。ha-all
(策略名称)^ha\.
(匹配的队列模式)ha-mode
-> all
ha-mode
是核心参数,它有几种不同的值:
all
:镜像到集群中的**所有节点**。
'{"ha-mode":"all"}'
exactly
:镜像到**指定数量**的节点上。
ha-params
使用。'{"ha-mode":"exactly", "ha-params": 2}'
nodes
:镜像到**指定节点名称**的节点上。
ha-params
使用。'{"ha-mode":"nodes", "ha-params": ["rabbit@node1", "rabbit@node2"]}'
node1
和 node2
上。除了 ha-mode
,还有其他重要参数:
ha-sync-mode
:镜像队列的同步方式。manual
(默认):手动同步。新镜像加入时,默认不同步,需要管理员手动触发或等待主队列故障转移。**不推荐用于生产环境**,因为可能导致数据丢失。automatic
:自动同步。当新镜像加入时,会自动同步所有数据。**推荐生产环境使用**,但同步期间队列会阻塞,无法读写。
'{"ha-mode":"all", "ha-sync-mode":"automatic"}'
ha-promote-on-shutdown
:控制当主队列所在节点**正常关闭**时,如何提升镜像。
when-synced
(推荐):只有当镜像与主队列完全同步时,才会被提升为主队列。这是最安全的选择。always
:总是提升最老的镜像,即使它不同步。这可能导致数据丢失。ha-promote-on-failure
:控制当主队列所在节点**意外故障**时,如何提升镜像。
when-synced
:同上,推荐。always
:同上。ha-sync-mode: automatic
:确保新加入的镜像能立即拥有完整数据,避免故障转移时数据丢失。exactly
模式:对于一个 3 节点的集群,"ha-mode":"exactly", "ha-params": 2
是一个很好的平衡点,它提供了冗余,同时避免了 all
模式在 5 个或更多节点时带来的巨大开销。ha.test
的队列。通过以上步骤,你就可以成功配置和管理 RabbitMQ 的镜像模式,从而构建高可用的消息队列服务。