分布式事务实战--本地消息表, rocketmq


源码

源代码: https://github.com/rudolflin/transaction-demo.git
依赖: consul(其实用不到, 只是为了做分布式事务未拆分前的demo使用) ,mysql ,rocketmq

以下部分全部摘自源码中的readme文件,图片懒得copy了,建议参考源代码.

分布式事务--本地消息表, rocketmq

  • 采用消息中间件实现, 其实就是保证两方面, 生产者侧本地事务执行成功后一定会发消息,发消息一定会到brocker(代码实现). 消费者测一定会不断重试,直到成功(mq实现),极端情况人工处理(代码实现)
  • 人工处理待开发

本地消息表方式

image-20210330175951030

demo a,b,c功能

  • a->b->c三个服务依次调用, 每个服务的account表都减同样数额的钱

    image-20210330180016001

特点

  • 最终一致性的前提是认为下游服务一定可以正确完成任务, 如果遇到突发事件, 通过重试最终也能完成.
  • 发消息通过本地事务表加定时任务完成,这个是本地消息表完成分布式事务的保证. 保证了本地事务执行一定会发消息,发消息一定会成功.
  • 服务消费要实现幂等, 但是要注意处理业务本地数据,写消息表(向下游发送消息),写去重表(幂等)要在一个本地事务里面.
  • 判断幂等要在做业务之前,标记成功标志要在业务之后, 尽量和业务分离开.
  • 目前想到的幂等方案只有去重表. 其他方案: 布隆过滤器(不是完全准确,有一定的错误率).关键在于,更新布隆过滤器和或者其他方案的去重标记, 要和业务事务,插入消息表等操作
    放在一起.否则可能出现, 业务做完了,做成功的标记没有打上.
  • 需要两张表: task表(记录要发送mq的任务-生产者使用), 去重表(记录那些消息处理过-生产者使用)

rocketmq事务方式

rocketmq事务消息

  • 需要两张张表: 1、本地事务记录表, 本地业务执行成功后, 保存一条记录, 供brocker反查,. 本地业务执行和记录事务成功状态要在一个本地事务里. 2、去重表(消费者使用,这种方式消息重复的概率较小)

  • 生产者是依靠第5步查询,保证本地事务执行后,消息一定会发送成功的。 其实就是定时任务部分的工作 ,由mq来做了。

  • 事务成功状态的保存, 要生成一个业务侧的key, 用于反查, 这个key可以放在(keys)字段里面 , 这样在messageExt中就能取到了.

  • 事务状态表, 里边其实只有一个事务id就可以了, 事务状态不是必须的 , 因为只要存进来的, 都是成功的, 否则就是失败了, 也存不进来.

  • service层将参数信息处理后封装成model . 然后发mq, 这里是没有事务控制的. 真正的业务和存消息表另起一个service执行. 由mqlistener自动调用执行. 时机是在发送半消息成功之后.

  • transactionid, 直接使用sendmessageintransaction之后,excutelocaltransaction中传入的message中的id即可.

    image-20210407150102262

  • unknow其实只作为调试使用

  • 事务回查

  • image-20210407150223873

  • 消费者只是普通消费着, 做好幂等即可

  • rocketmq 回查超过一定次数, 就会rollback消息

  • 监控报警部分: 需要监控死信队列 ,或者在消息消费时做记录, 失败时存一下记录, 当失败多次后出发邮件报警. 因为死信触发的时间比较长,或者直接改这个死信时间间隔和次数也可以, 正常情况下 , 两三次失败后, 下次也会失败. (两三次失败时为了兼容网络抖动等的影响), 然后做一个消费者组消费死信队列, 触发人工报警, 将异常信息放入另一个topic或者数据表里, 等待人工修复.

报警部分待补充

  • rocketmq的回查次数 ,频率,

  • 死信队列 报警(人工介入), (下游执行失败)

    • 重试队列是以%RETRY%+consumerGroup作为维度的生成consumeQueue。
    • 死信队列是以%DLQ%+consumerGroup作为维度的生成consumeQueue。
    • 进入死信队列的条件是重试次数超过了最大重试次数。
    • 死信队列的topic是在消息发送过程中判断对应的topic是否存在,不存在就动态进行创建。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM