一、背景
事务消息的定义:
- 在RabbitMQ中的事务消息是指多条消息的事务原子性
- 分布式事务,本地事务和消息中间件的一致性
本篇主要说的是本地事务和消息中间件的一致性,即分布式事务中的可靠性消息解决方案
二、分布式事务的理论
- CAP
- 一致性(Consistency)
- 可用性(Availability)
- 分区容错性(Partition tolerance)
- BASE
- Basically Available(基本可用)
- Soft state(软状态)
- Eventually consistent(最终一致性)
分布式事务解决思路都是BASE
柔性事务,使用重试策略保证数据的最终一致性,在同一时间片内数据可能不一致,强一致性场景需要考虑一致性读
三、事务消息的实现
市面已经存在事务消息开源的实现方案:
- QMQ基于Spring平台事务管理器的JDBC事务方案 通过代理客户端,保存事务消息信息到DB,与本地事务一起提交,异步和补偿定时任务发送消息中间件中,保证原子性,牺牲性能保证消息可靠性,场景在于可靠性要求高的交易业务。
如果业务对于消息丢失率容忍,可以优化为Redis存储,在发送失败时才异步放入redis重试队列中,这样性能可以大大提高
- RocketMQ两段消息事务消息方案
通过改写Topic
和Queue
将消息发送事务消息halfQueue
中,确认后修改OpQueue
提交,定时任务发送回生产者回查提交状态Commit
或者Rollback
,保证事务消息在消费者的可见性
缺点:
- 生产者业务有侵入,需要自己实现回查方法
- 对性能有一定影响,需要发送两次消息,多一个queue
不侵入方案,可以提供模板方案统一保存在Rds
或者NoSql
中消息Id的Commit
状态,回查方法直接查看状态
第二种方案只有RocketMQ
提供了实现,RabbitMQ
如果没有中间件团队应该选择第一种方案
四、平台化
消息平台化后应该事务消息跟消息中间件无关化,跟业务落地方案无关化,可以参考RocketMQ的二段提交,转发到事务消息队列,事务消息模块消费,然后注册一个回查延迟消息,回调生产者事务提交检查方法,完成事务