消息一致性保障:从发送到消费的全链路解决方案
消息一致性是分布式系统中消息队列使用的核心挑战,指业务操作与消息传递的状态保持一致:业务成功时消息必须正确发送并被处理,业务失败时消息不应被发送或需被撤回。本文从消息发送一致性和消息消费一致性两方面,解析问题根源与解决方案。
消息发送一致性:确保业务与消息的原子性
消息发送一致性的核心目标是:业务操作成功 ↔ 消息必须发送成功,避免 “业务成功但消息丢失” 或 “业务失败但消息发送” 的矛盾场景。
消息发送可能出现的问题
(1)业务成功但消息未发送
- 场景 1:业务逻辑执行完成后,应用在发送消息前宕机(如 JVM 崩溃),导致消息未发送。
- 场景 2:业务成功后,消息发送时消息中间件宕机(如 Broker 崩溃),消息未被持久化。
(2)业务失败但消息已发送
- 场景:消息先发送成功,但后续业务逻辑执行失败(如数据库事务回滚),导致无效消息被消费。
解决方案:基于 “消息预存 + 状态确认” 的两阶段方案
用户提到的方案本质是 “预发送消息→执行业务→确认消息可用” 的两阶段模式,确保业务与消息状态同步。具体流程如下:
步骤拆解:
- 预存消息:业务应用先向消息中间件发送 “待确认” 消息(状态标记为
未处理),消息中间件仅存储消息但不投递。- 目的:先确保消息能被中间件持久化,避免后续业务成功后消息发送失败。
- 消息中间件反馈存储结果:中间件返回 “消息存储成功 / 失败”。
- 若失败:业务直接终止(避免业务成功但消息无法存储)。
- 执行业务逻辑:仅当消息存储成功后,才执行核心业务(如订单创建、库存扣减)。
- 确认消息状态:业务执行完成后,向中间件发送 “业务结果”:
- 业务成功:中间件将消息状态改为
可投递,并向消费者投递。 - 业务失败:中间件删除预存消息(或标记为
废弃),避免无效消息。
- 业务成功:中间件将消息状态改为