1. 了解 MQ


  • 一款分布式消息中间件,基于 erlang 语言开发,具备语言级别的高并发处理能力。
  • RabbitMQ 和 Spring 框架是同一家公司。
  • 支持持久化、高可用。
5 个核心概念
  • Queue:真正存储数据的地方。
  • Exchange:接收请求,转存数据。
  • Bind:收到请求后存储到哪里。
  • 消息生产者:发送数据的应用。
  • 消息消费者:取出数据处理的应用。

2. 分布式事务问题


1. 分布式事务的几种解决方案
  • 基于数据库 XA/JTA 协议的方式;(需要数据库厂商支持;JAVA 组件有 atomikos 等;)
  • 异步校对数据的方式;(支付宝、微信支付主动查询支付账单、对账单的形式;)
  • 基于可靠消息(MQ)的解决方案;(异步场景;通用型较强;扩展性较强;)
  • TCC 编程式解决方案。(严选、阿里、蚂蚁金服自己封装的 DTX)
2. 美团点评系统架构
3. 分布式事务问题
  • 常见场景:
  • 代码执行成功,但是事务提交失败,导致调用第三方事务无法回滚。
  • 调用第三方超时,本平台事务回滚,第三方执行成功。

3. 实现分布式事务


1. 整体设计思路
  • 可靠生产:保证消息一定发送到 Rabbitmq 服务。
  • 可靠消费:保证消息取出来一定正确消费掉,最终多方数据达到一致。
2. 五个步骤
  1. 可靠消息生产-记录消息发送
  • 为了确保数据一定成功发送到 MQ。
  • 在同一事务中,增加一个记录表的操作。记录每一条发往 MQ 的数据以及它的发送状态。
  1. 可靠消息生产-修改消息发送状态
  • 利用 RabbitMQ 的发布确认机制(confirm)。
  • 开启发布确认机制后,MQ 准确受理消息会返回回执。
  • 如果出现回执没收到、消息状态修改失败等特殊情况。兜底方案:定时检查消息表,超时没发送成功,再次重发。
  1. 可靠消息处理-正常处理
  • 开启手动 ACK 模式。由消费者控制消息的重发/清除/丢弃。
  • 幂等性。防止重复处理,一次用户操作,只对应一次数据处理。
  1. 可靠消息处理-消息重发
  • 消费者处理失败,需要 MQ 再次重发给消费者。
  • 出现异常一般会重试几次,由消费者自身记录重试次数,并进行次数控制。

go语言分布式事务解决方案 golang分布式事务解决方案_go语言分布式事务解决方案

  • 消费者处理失败,直接丢弃或者转移到死信队列(DLQ)。
  • 重试次数过度、消息内容格式错误等情况,通过线上预警机制通知运维人员。

4. 总结及扩展


优缺点
  • 优点:
  • 通用性强
  • 扩展性强
  • 方案成熟
  • 缺点:
  • 基于消息中间件,只适合异步场景。
  • 消息处理会有延迟,需要业务上能够容忍。
建议
  • 尽量避免分布式事务;
  • 尽量将非核心业务做成异步。
分布式事务解决方案的理论依据
  • CAP 理论
  • BASE 理论
  • 2PC 协议
  • 3PC 协议
  • Paxos 算法
  • Raft 一致性协议