logo头像
Snippet 博客主题

从分布式事务理论,总结途牛火车票的解决方案

本文于 850 天之前发表,文中内容可能已经过时。

为解决单机系统的性能瓶颈,无论我们根据业务垂直拆分系统,还是水平分库分表,都会面临分布式事务的问题。解决此类分布式事务的场景,业内已经提出了一致性原理,如数据库单机的ACID,到后面提出的CAP和BASE定理,继而提出了一致性协议,如2PC,3PC,TCC,最后总结出实现最终一致性的方案。

  • 查询模式
  • 补偿模式
  • 异步确保模式
  • 定期校对模式
  • 支持事务的MQ

那么我做了三年的途牛火车票系统采用的是什么解决方案呢?我们用的也是业界常用的异步确保模式

异步确保模式核心理论是  将分布式事务转成本地事务处理,具体做法就是在每个业务系统维护一个本地消息记录表,
每次发起请求,记录下请求消息状态,也就是将业务数据与消息表放在一个数据库事务中提交,
系统之间可以使用MQ来传递消息,如果消费失败,或者消息没有发送出去,则通过消息表进行补偿。

分布式事务

异步确保模式的弊端就是维护了一份冗余的消息表,需要渗透到业务代码,不过先人也为我们考虑好了解决方案,这一块对消息表的操作已经被封装到rpc客户端的底层代码维护 ,业务系统无需要关心这块的处理。

途牛火车票的实践

途牛火车票系统之间,每个系统都有一个请求日志表,系统之间本质是http作为通信协议,底层封装了tsp的客户端请求工具,分布式事务是靠业务方自己实现本地消息表的方案,
比如我负责的订单系统,占位,出票,退票,都有记录系统之间的日志表,然后通过日志表的状态进行选择重试或者之间结束流程,以确保系统的最终一致性。
比如有一堆订单卡在中间状态,比如占位中,如果消息表没有记录,或者是同步没有反馈,又或者是同步反馈失败,订单系统作为上游系统直接对客失败处理。

这样的系统设计还存在哪些优点与缺点?

  1. 生产者/消费者的消息持久化,防止消息丢失
  2. 消息表的定期清理,防止数据量过多影响查询性能。
  3. 业务数据与消费发送MQ要在一个事务内执行,确保消息的可靠性。
  4. 不支持回滚,依托BASE理论,保证最终一致性

附录

聊聊分布式事务,再说说解决方案