RabbitMQ 的可靠性是一条端到端责任链:生产者确认消息被接收,Broker 持久保存并正确路由,消费者完成本地事务后确认。只开启消息持久化,仍可能在其他窗口丢失或重复。
Table of contents
逐段关闭故障窗口
生产者为每条消息分配业务事件 ID,异步等待 Confirm;连接中断时,未确认消息状态未知,应从 Outbox 重新发布。重复发布是正常结果,因此消费者必须幂等。
消费者常用顺序是:开始本地事务,插入 processed_message 唯一键,执行业务写,提交,再 ack。若提交后、ack 前崩溃,消息会重投,但唯一键阻止副作用重复。
死信不是垃圾桶
消息被拒绝且不重新入队、TTL 到期、队列超长,或 Quorum Queue 超过投递次数时,可以进入死信交换机。优先用 Policy 配置死信交换机,便于在线修改。参考 RabbitMQ Dead Letter Exchange了解触发条件。
延迟重试可用多级 TTL 队列或受支持的延迟机制。重试消息应记录次数、首次失败时间和错误类别;超过预算后进入隔离队列,并有重放工具。重放仍要保留原事件 ID。
顺序是局部属性
一个队列一个消费者容易保持处理顺序,却牺牲吞吐。多消费者时可按 orderId 分片到固定队列,每个分片串行处理。失败重试可能阻塞后续消息,业务需决定是严格等待还是允许跳过并补偿。
以下测试验证重复事件只产生一次余额变化:
mvn -Dtest=DistributedMechanismsTest#outboxAndIdempotentConsumerSurviveDuplicates test
监控 Confirm 延迟与未确认数、不可路由数、ready/unacked 消息、最老消息年龄、重投率和死信增长。只看队列长度会漏掉消费者卡住但消息全处于 unacked 的情况。
下一步
继续阅读08-14 RabbitMQ 集群、Quorum Queue 与运维,把单队列语义扩展到集群故障。