RabbitMQ 4.x 消息可靠性:确认、重试、死信与幂等
基线:RabbitMQ 4.x 或当前受支持的 3.13+,Java 客户端版本与服务端兼容。不要使用 latest,也不要使用默认密码。
1. 生产链路
Publisher -> Exchange -> Queue -> Consumer
| |
publisher confirm ack/retry/dead letter
生产者确认解决“消息是否被 Broker 接收”,消费者 ack 解决“消息是否被成功处理”。两者不是一回事。
2. 发布端可靠性
启用 publisher confirms,只有收到 Broker 确认后才认为发布成功。应用仍要处理 nack、连接断开和超时,并用业务消息 ID 做幂等。
消息持久化、持久化 exchange/queue 和 confirms 共同降低丢失风险,但不等于业务已经成功处理。对于关键事件,建议使用本地消息表或 Outbox,把数据库状态和待发送消息放在同一事务中。
3. 消费端处理
消费者应在业务处理成功后 ack;临时故障可以有限重试,无法处理的消息进入死信队列。重试必须有次数和退避上限,不能无限 requeue,否则会形成热循环。
消费逻辑必须幂等。网络重试、消费者重启和 ack 丢失都可能让同一消息再次投递。
4. 高可用和延迟消息
高可用场景优先评估 quorum queues。classic queue、镜像策略和延迟插件的行为取决于 RabbitMQ 版本,不能直接复制 3.8 时代的部署命令。
延迟消息可评估 TTL + DLX、插件、Streams 或业务调度器,选择前要确认顺序、重试、容量和运维成本。
5. 安全与监控
为每个应用创建最小权限用户,管理端启用 TLS 和访问控制。监控 confirms、nack、unacked、队列深度、消费延迟、重试次数和死信数量。设置 prefetch,避免单个消费者一次持有过多未确认消息。