生产环境里的 RabbitMQ 如果要扛住真实业务流量,单节点基本撑不了多久。内存被打满、磁盘告警、连接数飙升,任何一个坑都够运维喝一壶。我见过不少团队上了 RabbitMQ 集群,结果客户端只配了一个节点地址,节点一挂业务直接瘫痪。后来想明白了一件事:集群归集群,入口必须统一。本文就围绕“RabbitMQ HAProxy 负载均衡”这条主线,讲讲为什么要在 RabbitMQ 集群前面加一层 HAProxy,HAProxy 该怎么配置、健康检查怎么设计、客户端怎么接入,以及我在实际部署中踩过的一些坑。适合正在做 RabbitMQ 集群高可用改造、或者想理解消息中间件接入层设计的朋友参考。
1. 整体方案设计与选型思路
1.1 为什么要在 RabbitMQ 前面加一层 HAProxy
很多初学者对“集群”有个误解,觉得把三个 RabbitMQ 节点组成集群,客户端随便连哪个都行。理论上是这样,但实际生产中会遇到三个很现实的问题。
第一,客户端配置的是固定 IP。如果集群里某个节点宕机了,客户端不知道要切换地址,除非你在代码里写死多个地址并自己实现故障转移。大多数业务团队不会这么干,也不应该这么干。
第二,节点扩容或者缩容时,客户端配置要跟着改。今天三个节点,明天加到五个,所有客户端连接串都要动一遍,这是灾难级的运维成本。
第三,连接不均衡。三个节点,有的客户端连 A,有的连 B,有的连 C,时间一长每个节点的连接数和负载完全不一样,资源利用率很差。
HAProxy 在中间起的作用就是一个“统一入口”。它对外暴露一个虚拟地址和端口,客户端只认这一条路,HAProxy 再把请求按策略转发给后端的 RabbitMQ 节点。后端的节点挂了、加了、换了,客户端完全无感知,运维只需要改 HAProxy 配置就够了。
有人可能会问:用 Nginx 做 TCP 转发不行吗?行,Nginx 从 1.9 开始支持 stream 模块,也能做四层代理。但 HAProxy 在负载均衡算法、健康检查、连接调度、统计监控这些方面更成熟,尤其是对长连接场景的支持和细粒度的连接管理,HAProxy 明显更顺手。身边做消息中间件运维的朋友,绝大多数用的都是 HAProxy。
1.2 负载均衡方案的横向对比
为了把选型逻辑讲清楚,我列一下常见方案的对比,包括客户端多地址、Nginx TCP 代理、HAProxy、LVS 这几种。
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 客户端多地址 | 无需额外组件,实现简单 | 客户端配置复杂,节点变化要改应用配置,故障转移依赖客户端实现 | 测试环境、节点极少且不扩容的场景 |
| Nginx stream 模块 | 运维熟悉度高,和 Web 服务共用一套体系 | 长连接场景参数调节不如 HAProxy 灵活,健康检查能力较弱 | 已有 Nginx 体系且不想引入新组件的小规模场景 |
| HAProxy | 负载均衡算法丰富,健康检查灵活,统计页强大,四层性能极高 | 自身是单点,需要配合 Keepalived 做高可用 | 中小规模 RabbitMQ 集群最推荐 |
| LVS | 性能天花板最高,支持大规模流量 | 部署复杂,配置门槛高,一般要配合 Keepalived 和专业运维 | 超大规模、请求量每秒数万以上的场景 |
另外提一个容易混淆的点:像 OpenFeign 内部集成的负载均衡(比如 Ribbon、Spring Cloud LoadBalancer)是客户端侧的负载均衡,属于“调用方自己做选择”的模式。而 HAProxy 这种是服务端接入层的负载均衡,对客户端透明。两者不是同一个层面,别搞混了。
从成本和收益角度综合考虑,大部分团队选 HAProxy 是最合理的。单机 HAProxy 跑满十万级并发连接毫无压力,对 RabbitMQ 这种规模的消息中间件来说完全够用。如果担心 HAProxy 自身单点,后面再加 Keepalived 做 VIP 漂移,这个我后面会展开讲。
1.3 “等开销负载均衡”到底是什么意思
热搜词里有个“等开销负载均衡”,我理解大家想问的是:负载均衡是怎样做到让每个后端节点的开销大致相等的。这里的“开销”可以理解为连接数、CPU、内存、网络带宽等资源消耗。
HAProxy 的 roundrobin(轮询)算法,就是让请求按顺序轮流分发到每个后端节点,每个节点接收的请求数量大致相同,这是一种“等开销”的思路。但实际生产中有个问题:RabbitMQ 的 AMQP 连接是长连接,客户端连上之后会一直保持,如果某个客户端发的消息量特别大,即使每个节点连接数差不多,节点间的真实负载也可能差异很大。
所以针对 RabbitMQ 这种长连接场景,我更推荐 leastconn(最小连接数)算法。HAProxy 会实时统计每个后端的活跃连接数,新连接永远分给当前连接数最少的节点。这样能在连接分配层面做到更贴近“等开销”的效果。具体配置用哪种,后面配置章节我会给出建议。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. RabbitMQ 集群准备
2.1 节点规划与端口说明
在配置 HAProxy 之前,前提是要有一个健康的 RabbitMQ 集群。以三节点为例,我通常会这样规划:
| 节点 | 角色 | IP | 说明 |
|---|---|---|---|
| rabbit1 | 磁盘节点 | 192.168.1.21 | 集群元数据持久化节点 |
| rabbit2 | 磁盘节点 | 192.168.1.22 | 可故障转移 |
| rabbit3 | 内存节点 | 192.168.1.23 | 内存节点,重启后从磁盘节点同步元数据 |
需要说明的是,RabbitMQ 集群要求至少有一个磁盘节点。如果全部都是内存节点,重启后元数据会丢失。生产环境我一般建议全部用磁盘节点,尤其是节点数量不多的时候,磁盘节点更省心。
端口方面要清楚每个端口的作用:
| 端口 | 用途 |
|---|---|
| 5672 | AMQP 协议端口,客户端连接和消息收发走这个 |
| 15672 | Management 管理界面,Web 管理端口 |
| 25672 | 集群节点间通信端口,RabbitMQ 节点互联用 |
| 4369 | EPMD 端口,节点发现用 |
HAProxy 只需要暴露 5672 给客户端,15672 可以根据需要决定是否暴露。节点间的 25672 和 4369 不需要经过 HAProxy,保持集群直连即可。
2.2 Docker Compose 快速搭建三节点集群
如果你是在测试环境验证方案,用 Docker Compose 起集群最快。下面是一个我常用的三节点配置。
yaml复制services:
rabbit1:
image: rabbitmq:3.12-management
hostname: rabbit1
environment:
- RABBITMQ_ERLANG_COOKIE=SECRET_COOKIE_VALUE
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=admin123
ports:
- "5672:5672"
- "15672:15672"
rabbit2:
image: rabbitmq:3.12-management
hostname: rabbit2
environment:
- RABBITMQ_ERLANG_COOKIE=SECRET_COOKIE_VALUE
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=admin123
ports:
- "5673:5672"
- "15673:15672"
rabbit3:
image: rabbitmq:3.12-management
hostname: rabbit3
environment:
- RABBITMQ_ERLANG_COOKIE=SECRET_COOKIE_VALUE
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=admin123
ports:
- "5674:5672"
- "15674:15672"
这里有个关键点:三个节点的 RABBITMQ_ERLANG_COOKIE 必须一致,否则节点之间无法互相认证,集群根本组建不起来。这也是新手最常见的报错原因。
容器启动后,进入 rabbit2 和 rabbit3 分别执行加入集群的命令:
bash复制docker exec -it rabbit2 rabbitmqctl stop_app
docker exec -it rabbit2 rabbitmqctl join_cluster rabbit@rabbit1
docker exec -it rabbit2 rabbitmqctl start_app
docker exec -it rabbit3 rabbitmqctl stop_app
docker exec -it rabbit3 rabbitmqctl join_cluster rabbit@rabbit1
docker exec -it rabbit3 rabbitmqctl start_app
注意 join_cluster 的参数是“节点名@主机名”,这里的 hostname 要和容器 hostname 一致。Docker 默认容器名就是 hostname,所以上面 rabbit@rabbit1 能解析到 rabbit1 容器。
2.3 镜像队列策略与高可用
集群搭好了,还有一个重要步骤:消息队列的高可用。RabbitMQ 默认的队列是普通队列,消息只存在某一个节点上,节点挂了队列就丢了。要让消息在集群中多节点冗余,必须配置镜像队列。
我习惯把策略设置为匹配所有队列,并且自动同步:
bash复制rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
这条命令的意思是:所有名称匹配 ^(即全部)的队列,镜像到集群所有节点,同步模式为 automatic。这样任何一个节点宕机,消息还在其他节点上有副本,客户端通过 HAProxy 连接到其他节点后,队列和消息依然可用。
需要提醒的是,从 RabbitMQ 3.13 开始,官方把镜像队列标记为旧特性,推荐使用 quorum queue(仲裁队列)。quorum queue 本身就是多副本设计,更适合数据可靠性要求高的场景。如果你用的是 3.13 以上的新版本,新建队列时可以直接声明为 quorum 类型,不需要依赖镜像策略。不过镜像策略在存量系统中仍然大量存在,这块知识没过期。
2.4 验证集群状态
集群配置完,先别急着上 HAProxy,确认一下集群本身是健康的。
bash复制rabbitmqctl cluster_status
重点关注输出里的 Disk Nodes 和 Running Nodes,正常情况下三个节点都应该在里面,而且状态是 running。然后可以写一个简单的生产者消费者脚本发几条消息,确认消息能正常收发。
我遇到过一种情况:三个节点都显示 running,但集群处于分区状态(partition),节点之间无法同步。这种状态非常隐蔽,表面看起来一切正常,但队列镜像和消息复制其实是断裂的。排查方法是用 rabbitmqctl list_queues name mirror_pids 看每个队列的镜像进程,如果只有一个节点的 pid,说明镜像没建起来。
3. HAProxy 配置与负载均衡实现
3.1 安装 HAProxy
HAProxy 的安装比较简单,主流 Linux 发行版都有现成的包。
bash复制# Ubuntu / Debian
apt update && apt install -y haproxy
# CentOS / RHEL
yum install -y haproxy
版本建议使用 2.4 以上,新版本支持多线程、更好的连接队列管理,配置语法也更完善。装完先看一下版本号确认一下。
bash复制haproxy -v
3.2 核心配置讲解
HAProxy 的配置文件是 /etc/haproxy/haproxy.cfg。下面是我针对 RabbitMQ 场景整理的一份完整配置,配合注释看会很清晰。
haproxy复制global
log /dev/log local0
maxconn 8192
nbthread 4
user haproxy
group haproxy
defaults
log global
mode tcp
option tcplog
option dontlognull
timeout connect 5s
timeout client 120s
timeout server 120s
frontend rabbitmq_frontend
bind *:5672
default_backend rabbitmq_backend
backend rabbitmq_backend
mode tcp
balance leastconn
option httpchk GET /api/health/checks/alarms
http-check expect status 200
server rabbit1 192.168.1.21:5672 check port 15672 inter 5s fall 3 rise 2
server rabbit2 192.168.1.22:5672 check port 15672 inter 5s fall 3 rise 2
server rabbit3 192.168.1.23:5672 check port 15672 inter 5s fall 3 rise 2
listen rabbitmq_stats
bind *:8404
mode http
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:admin123
下面逐个部分拆解说明。
frontend 是入口,bind *:5672 表示监听所有网卡的 5672 端口。default_backend 指定转发到哪个后端。
backend 是实际的服务节点池。三个 server 对应三个 RabbitMQ 节点,端口都是 5672。注意最后的 check port 15672,这个非常关键,意思是 HAProxy 对后端节点的健康检查不直接打 5672,而是打 15672 管理端口。为什么这么做,下一节详细讲。
balance leastconn 是我推荐的长连接负载均衡算法。如果是短连接场景,roundrobin 就够了。但 AMQP 是长连接,客户端一旦连上可能几个小时都不断开。用 roundrobin 虽然连接数理论上会均分,但实际每个连接的消息吞吐量不一样,导致某些节点连接数不多但负载很高。leastconn 会优先把新连接分配给当前连接数最少的节点,更贴近真实的“等开销”。
3.3 健康检查才是关键
健康检查是整个负载均衡方案里最容易翻车的部分,我说说原因。
最简单的健康检查方式是 TCP 探测:HAProxy 定期跟后端节点的 5672 端口建立连接,能连上就认为节点健康。这配置很简单:
haproxy复制option tcp-check
tcp-check connect
但这里有个坑:RabbitMQ 进程可能已经假死,比如 Erlang 虚拟机卡死、磁盘写入阻塞导致服务无法处理消息,但操作系统层面的 5672 端口还在监听。TCP 探测发现端口能连通,判定节点健康,于是 HAProxy 继续把连接转发过去,客户端发消息就卡死或者超时。
生产环境我更推荐用 RabbitMQ 管理 API 做健康检查。RabbitMQ 3.8 之后提供了专门的健康检查接口:
bash复制GET /api/health/checks/alarms
这个接口返回 200 表示节点没有触发内存或磁盘告警,返回 400 表示节点处于 alarm 状态,不再接受消息写入。通过它做健康检查,能准确反映节点是否真实可用,而不是简单地看端口通不通。
对应到 HAProxy 配置就是:
haproxy复制option httpchk GET /api/health/checks/alarms
http-check expect status 200
server rabbit1 192.168.1.21:5672 check port 15672 inter 5s fall 3 rise 2
这里的逻辑是:HAProxy 每 5 秒访问一次节点的 15672 管理端口,检查 /api/health/checks/alarms 接口,返回 200 认为节点健康,连续 3 次失败标记为宕机,连续 2 次成功标记为恢复。注意健康检查请求走 15672,但真实业务流量依然走 5672,互不干扰。
接口本身不需要认证,因为这是 RabbitMQ 内置的只读健康检查端点,不涉及管理操作。我用这个方案替换掉 TCP 探测后,节点假死的问题基本没再出现过。
3.4 管理统计页配置
HAProxy 自带的统计页非常实用,可以实时看到每个后端节点的连接数、健康检查状态、流量转发情况。我在配置文件里加了一个 listen rabbitmq_stats,监听 8404 端口。
访问 http://192.168.1.200:8404/stats,输入配置的账号密码就能看到监控面板。重点关注这几个指标:
| 指标 | 含义 |
|---|---|
| Sessions Total | HAProxy 启动以来的总连接数 |
| Cur | 当前活跃连接数 |
| Bytes In/Out | 转发流量大小 |
| Status | 后端节点状态,UP 或 DOWN |
| LastChk | 最近一次健康检查的结果 |
生产排障的时候,我第一时间就是开这个页面看后端节点状态。如果一个节点 Status 变成 DOWN,但实际 RabbitMQ 是好的,多半是健康检查配置有问题,比如 15672 端口没开放或者管理插件没启用。
3.5 参数与性能调优
HAProxy 的默认参数在小流量下没问题,但生产环境建议关注几个关键参数。
maxconn 控制最大连接数。默认值偏保守,我一般设成 8192 起步,如果预估客户端连接数上千,可以考虑调到 20000 以上。同时要注意操作系统层面的文件描述符限制(ulimit -n),HAProxy 的 maxconn 再高,系统限制不够也白搭。
nbthread 是 HAProxy 的工作线程数,一般设置为 CPU 核心数即可。老版本用 nbproc 开启多进程,但多进程之间有连接分配不均的问题,新版本用多线程更稳定,配置也简单。
timeout client 和 timeout server 是读写超时,AMQP 长连接场景不能设太短。RabbitMQ 客户端默认心跳是 60 秒,如果 HAProxy 的超时时间小于 60 秒,正常的空闲连接会被误判为超时断掉。我推荐设置成心跳间隔的两倍以上,即 120 秒以上。配置里我写的是 120s,实际如果客户端心跳改了,这里也要跟着调。
还有 timeout queue,这个参数控制等待后端连接队列的超时时间。后端节点全部繁忙时,新连接会在 HAProxy 的队列里等待,如果等待时间过长就返回错误。默认值是 30 秒到一分钟,如果你的业务对连接建立延迟敏感,可以缩短这个值,让客户端快速失败并重试,而不是一直阻塞。
4. 客户端接入与故障转移验证
4.1 Spring Boot 连接配置
配置好 HAProxy 之后,客户端就不需要知道后端集群有哪些节点了,只需要连接 HAProxy 的地址。以最常见的 Spring Boot 项目为例,配置如下。
yaml复制spring:
rabbitmq:
addresses: 192.168.1.200:5672
username: admin
password: admin123
virtual-host: /
connection-timeout: 5000
cache:
connection:
mode: channel
listener:
simple:
acknowledge-mode: auto
retry:
enabled: true
addresses 填 HAProxy 的地址和端口,而不是 RabbitMQ 节点的真实地址。用户名密码是 RabbitMQ 里创建的账号,HAProxy 不做认证,只是转发流量。
有一点要注意:virtual-host 默认是 /,如果你的 RabbitMQ 创建了独立的 vhost,这里要对应修改。否则会出现连接成功但权限不足,消费者拿不到消息的诡异问题。
4.2 生产验证:故障转移实测
配置完一定要做一次故障转移演练,不要等线上出问题才验证。我通常这样做:
- 启动生产者和消费者,确认消息收发正常。
- 在 HAProxy 统计页确认三个节点都是 UP 状态。
- 手动停掉其中一个 RabbitMQ 节点(比如 rabbit1)。
- 观察 HAProxy 统计页:rabbit1 的 Status 从 UP 变成 DOWN,健康检查连续失败触发熔断。
- 继续发消息,确认生产者没有报错,消息能正常送达消费者。
这里要给大家提个醒:HAProxy 只负责转发新连接。如果客户端在 rabbit1 宕机之前已经建立了一条 TCP 连接,这条连接会断开,客户端需要重新发起连接。所以客户端侧的连接恢复机制很重要。Spring Boot 的 Spring AMQP 内置了连接恢复(默认开启),会自动重连。我们项目中配置了 retry.enabled=true,重连失败后会按策略重试,确保消息不丢。
实测下来,从节点宕机到客户端自动重连成功,耗时通常在三到五秒之间,具体取决于健康检查的 inter 时间和客户端的重连间隔。对大多数业务来说,这个中断窗口是可以接受的。如果业务要求更高的可用性,那就需要客户端本地缓存或者消息重发机制兜底。
4.3 高可用方案的下一步:Keepalived VIP
前面说过 HAProxy 本身是单点,它挂了,所有客户端连接全部中断。解决思路就是再加一台 HAProxy,配合 Keepalived 做 VIP 漂移。
两台 HAProxy 一台主一台备,共用同一个 VIP(虚拟 IP),比如 192.168.1.200。正常情况下 VIP 绑定在主 HAProxy 上,客户端连的是 VIP。主 HAProxy 宕机后,Keepalived 把 VIP 漂移到备机,客户端连接中断后会通过重连机制连上新机器,整个过程对业务基本无感。
配置 Keepalived 的核心是健康检查脚本,每隔几秒检查 HAProxy 进程是否存活。进程挂掉就触发 VIP 漂移。两个 HAProxy 的 haproxy.cfg 保持完全一致,确保无论 VIP 漂移到哪台,转发策略都一样。
还有更保险的做法:客户端配置两个 HAProxy 地址(比如 192.168.1.200:5672,192.168.1.201:5672),Spring AMQP 支持多地址自动选择。这样的话,即使 Keepalived 也出问题,客户端还能直连备机。不过这是双保险方案,大多数场景下 Keepalived 加 HAProxy 已经足够了。
5. 常见问题与排查技巧
5.1 节点假死:端口通但服务不可用
这是最常见也是最坑的问题。节点宕机还好排查,最怕的是 Erlang 虚拟机还活着、端口还能连,但 RabbitMQ 实际已经无法处理消息。我之前负责的一个项目就遇到过:RabbitMQ 节点磁盘读 IO 阻塞,管理界面打不开,但 5672 端口 TCP 能通,HAProxy 的 TCP 健康检查一直显示 UP,消息全部卡在队列里,消费者拿不到消息。
解决思路前面已经提到,就是改用 HTTP 健康检查接口。/api/health/checks/alarms 会检查 RabbitMQ 内部的内存告警和磁盘告警状态,只要有一个 alarm 未恢复就返回 400,HAProxy 就能及时把节点摘掉。
5.2 连接频繁被断开:心跳与 timeout 冲突
客户端连上 HAProxy 后,每隔一段时间就报“connection closed unexpectedly”,但节点本身健康。这个问题十有八九是心跳和超时参数不匹配。
默认 RabbitMQ 客户端心跳是 60 秒,每 60 秒发送一次心跳包保持连接。如果 HAProxy 配置的 timeout client 或 timeout server 小于 60 秒,HAProxy 会认为连接已经空闲超时,主动断开。客户端收到连接关闭通知,就会报错。
解决办法很简单:确保 HAProxy 的 timeout 大于客户端心跳周期的两倍。客户端心跳设 60 秒,HAProxy 就设 120 秒。如果你改了客户端的 heartbeat 参数,记得同步调整 HAProxy 的 timeout,这个坑我踩了好几次才总结出规律。
5.3 集群网络分区与脑裂
RabbitMQ 集群节点之间的网络抖动可能导致网络分区,节点之间互相看不到对方,每个节点都认为自己是集群的唯一成员。这时如果 HAProxy 还在向所有节点分发连接,就会出现两个节点各自为政,队列数据不一致的严重问题。
规避策略是配置 RabbitMQ 的网络分区处理策略。我一般设置为 pause_minority,意思是发生分区时,少数派节点自动暂停服务。这样 HAProxy 的健康检查会发现少数派节点不可用,把流量全部转到多数派节点,避免数据不一致。
bash复制rabbitmqctl set_cluster_partition_handling pause_minority
如果分区已经发生,恢复方法是在多数派节点上执行 rabbitmqctl start_app,让少数派节点重新加入集群。注意不要在分区期间对节点做重启等操作,否则可能引入新的数据不一致。
5.4 死信队列与消息堆积估算
经常有朋友问“死信队列 30 分钟会压多少消息”,这个问题其实要结合生产速率来算。假设你的业务每秒产生 500 条消息进入死信队列,TTL 设置 30 分钟(1800 秒),那么死信队列最多会累积:
500 条/秒 × 1800 秒 = 900000 条
如果每条消息平均 1KB,就是大约 900MB 的内存占用(假设消息都在内存中)。这还没算队列本身的开销和消费者处理延迟。所以不要以为死信队列是“垃圾桶”就放任不管,高峰期一样能把节点内存打爆。
我的建议是给死信队列单独设置长度限制和溢出策略:
bash复制rabbitmqctl set_policy dlx-max-length "^dlx\." '{"max-length":100000,"overflow":"drop-head"}'
这样即使消费速度跟不上,队列长度也不会无限膨胀,只会丢弃最老的消息,保住节点内存。同时要监控死信队列的消息积压数,超过阈值就报警。
5.5 连接风暴与批量重连
某个后端节点抖动后恢复,HAProxy 会立刻把新连接分给它,但如果此时集群里积压了大量消息,节点 CPU 飙升,又可能导致新一轮不可用。这时候成千上万个客户端同时重连 HAProxy,会形成连接风暴。
缓解办法有两个层面。HAProxy 层面,可以配置 timeout queue,对瞬间涌入的连接做排队限流。客户端层面,给 Spring Boot 的 RabbitMQ 配置连接工厂增加重试间隔指数退避:
yaml复制spring:
rabbitmq:
listener:
simple:
retry:
enabled: true
initial-interval: 1000
multiplier: 2
max-interval: 10000
这样做的好处是重连请求不会同时打过来,而是逐步增加间隔,给后端节点恢复留出时间。连接风暴这个问题平时看不出来,一旦发生就是连锁故障,提前预防非常重要。
5.6 常见问题速查表
| 问题现象 | 可能原因 | 排查思路与解决 |
|---|---|---|
| HAProxy 显示后端节点 DOWN | 15672 未开放或管理插件未启用 | 确认 rabbitmq-plugins enable rabbitmq_management,检查端口连通性 |
| 客户端连接后频繁断开 | HAProxy timeout 小于心跳周期 | 将 timeout client/server 调到心跳周期两倍以上 |
| 消息发出但消费者收不到 | 网络分区或镜像队列未建立 | 检查 cluster_status,确认队列 mirror_pids 是否多节点 |
| 内存告警持续触发 | 消息堆积过多 | 设置队列长度限制、死信队列溢出策略、减少消息体积 |
| HAProxy 单点故障 | 没有高可用方案 | 部署双 HAProxy + Keepalived VIP 漂移 |
| 集群节点全部 DOWN 但 CPU 正常 | Erlang Cookie 不一致 | 确认三节点 RABBITMQ_ERLANG_COOKIE 完全一致 |
最后再分享一个小技巧
配置全部上线后,建议在 HAProxy 的统计页盯一周,重点看每个节点的 Cur(当前活跃连接数)分布是否均匀。如果发现某个节点长期连接数明显偏高,把 balance leastconn 调出来检查一下,或者看看是不是客户端连接串里还残留了某个节点的直连地址,绕过了 HAProxy。这类问题日志不会报错,只能靠监控数据发现。我自己就因为排查这种连接不均的问题,发现了一个老项目里硬编码了节点 IP 的定时任务,改完后整个集群的负载瞬间均衡了很多。
