可靠的消息发送补偿机制采用“主线+备线”双轨设计:主线通过mq异步发送并启用确认机制,备线基于业务状态定时扫描补偿,全过程需幂等、可扩展、独立运行且与消费者幂等配合。

可靠的消息发送补偿机制,核心是“主线+备线”双轨设计:主线走消息队列(如 RabbitMQ/Kafka)实现高效异步;备线用定时扫描+业务校验兜底,确保即使 MQ 完全不可用或消息丢失,关键业务动作仍能最终完成。
主线发送必须带确认与失败捕获
不能只调用 convertAndSend 就认为消息已发出。要启用中间件的可靠性机制:
- RabbitMQ:开启发布确认(
channel.confirmSelect()),同步等待waitForConfirms()返回 true,否则记录失败并进入补偿队列 - Kafka:设置
acks=all+ 合理retries,生产者 send() 后检查回调中的 exception - 所有失败场景(网络超时、连接中断、拒绝投递)都需明确捕获,不吞异常,不静默丢弃
补偿任务必须基于业务状态,而非消息日志
补偿不是重发原始消息,而是重新识别“哪些该做但还没做”。例如用户注册后发欢迎消息:
- 在用户表加字段
sent_welcome_at(初始为 null) - 主线成功发送后,更新该字段为当前时间
- 补偿 Job 每分钟扫描
created_at 的用户,重新触发发送逻辑 - 补偿过程本身也要幂等:先尝试更新
sent_welcome_at(用 where 条件限制仅 null 可更新),成功后再发消息
补偿能力要匹配主线吞吐,且可独立运行
备线不是“偶尔跑跑”的辅助脚本,而是具备生产级承载力的独立流程:
- 补偿 Job 应支持水平扩展(如分片查询 user_id % N),避免单点瓶颈
- 执行器需自带重试、限流、失败告警,不依赖 MQ 正常工作
- 补偿周期建议设为 1–2 分钟,延迟可控;若业务强实时,可结合数据库 binlog 或 CDC 实时触发
- 上线前压测补偿链路:模拟主线完全中断 5 分钟,验证备线能否在 1 分钟内追平积压
消费者端必须配合幂等,形成闭环
补偿机制有效,前提是下游不会因重复消息出错:
- 欢迎消息消费者收到后,先查数据库确认该用户是否已标记
sent_welcome_at - 或者用唯一业务键(如
"welcome_" + user_id)写入幂等表,插入前加唯一索引约束 - 幂等校验必须覆盖整个副作用过程(如邮件实际发出、短信网关调用),不能只校验“消息被消费”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











