RabbitMQ 集群

单节点 RabbitMQ 受制于单机吞吐与故障面:节点挂了服务就断。集群把多个节点组成一个逻辑 broker,可横向扩展吞吐,配合高可用队列(见下章)还能在节点故障时继续对外服务。

为什么需要集群

  • 提升吞吐:多个节点分摊连接与路由压力;
  • 高可用:节点宕机时其它节点接管服务(前提是队列有副本,否则队列仍不可用);
  • 统一管理:一个集群一套账号权限、一个管理台。

节点类型:内存节点与磁盘节点

集群节点按元数据存储方式分为两类:

类型元数据存放说明
磁盘节点 disc磁盘(默认)持久保存队列、交换机、绑定、用户等定义
内存节点 ram仅内存重启后从磁盘节点同步,读写略快

集群必须至少保留一个磁盘节点来保存定义;生产环境建议全部使用磁盘节点,ram 节点只在特殊压测场景考虑。

组集群步骤

假设 node1 已运行,把 node2 加入组成两节点集群:

# 1. 在两台机器上保证 Erlang Cookie 一致:
#    把 node1 的 /var/lib/rabbitmq/.erlang.cookie 复制到 node2,
#    保持属主为 rabbitmq、权限 400,然后重启 node2 的 rabbitmq
# 2. 在 node2 上依次执行:
rabbitmqctl stop_app
rabbitmqctl reset                    # 清空 node2 独立的旧状态
rabbitmqctl join_cluster rabbit@node1
rabbitmqctl start_app
rabbitmqctl cluster_status
# 输出:Running Nodes: rabbit@node1 rabbit@node2
#       Partitions: []               # 无网络分区

Erlang Cookie 不一致时节点间认证失败,报 Node authentication failure 之类的错;join 前还要保证两边主机名能互相解析。让节点离开集群:本机 stop_app 后 reset 自退,或在其它节点上执行 rabbitmqctl forget_cluster_node rabbit@node2。

想在一台机器上模拟多节点实验,可用不同的 RABBITMQ_NODE_NAME 与 RABBITMQ_NODE_PORT(如 rabbit1@localhost:5673、rabbit2@localhost:5674)启动多个实例组集群,仅适合学习。

集群中的队列归属

集群队列主节点与副本 集群共享交换机、绑定、队列元数据与账号权限(由磁盘节点持久化),但经典队列的"消息本体"默认只存在声明它的那个节点上,即队列主节点:

  • 消费者连哪个节点都能收发,broker 内部会把请求路由到队列所在节点;
  • 主节点宕机时,其上单副本队列的消息会暂时不可用,直到节点恢复;
  • 想让消息也有副本,需要镜像队列或仲裁队列(见下章)。

集群通信端口

端口用途
4369epmd 节点发现
25672节点间集群通信
5672AMQP 客户端连接
15672管理台与 HTTP API

集群节点之间至少放通 4369 与 25672,云上部署还要检查安全组。

集群边界:federation 与 shovel

集群解决"同一逻辑集群内多节点"的扩展与高可用;跨集群(异地机房、异构环境)的数据迁移属于另一类工具:federation 按需把上游消息转发到下游,shovel 固定搬运某条链路。它们解决跨集群复制,替代不了集群内的队列副本。

小结

集群 = 统一逻辑 broker + 水平扩展:节点间靠一致的 Erlang Cookie 互信,stop_app → reset → join_cluster → start_app 即可加入,cluster_status 确认状态。记住默认队列是单副本这一前提,高可用必须靠镜像或仲裁队列补上。

笔记加载中…