- 分布式事务不适用微服务
- 首先 2pc 会出现同步阻塞和加锁,并且有单点故障,由于锁的原因又降低了吞吐量
- Nosql 数据库并不支持 2pc
- 在微服务架构下,使用最终一致性来替代分布式事务中的强一致性。
- 最终一致性:是指不同服务节点在一段时间后,节点间的数据会最终达到一致的状态
- 一般借助消息队列和内部表来完成
- 可靠事件模式是只要他的前序时间发生后序事件就一定发生
- 可靠性事件模式不能够回滚
- 发送消息前,记录消息 id,以及数据
- 发送消息,如果成功,通知原服删除记录;如果失败则重试,直到消息被消费
- 举例,支付宝的余额转到余额宝
- 用户发起请求调用支付宝扣款并记录该事件记录到数据库中
- 发送消息,经过消息队列,消息队列向余额宝服务进行投递消息
- 余额宝收到消息后进行加款并且记录事件到数据库中,通过事件 id 唯一的记录用户发起的一个转账事件
- 余额宝加款后会发送一个确认消息,经过消息队列投递给支付宝,支付宝收到这个消息之后就会 将本地数据库的事件进行删除
- 异常分析
- 余额宝服务宕机了,或消费消息失败了,就需要支付宝服务发起一个定时任务,定期的检测数据库中的事件记录,并发送消息,直到余额宝服务投递出确认消息
- 假如余额宝服务已经做了加款,那么下一次支付宝服务再发送重复的消息之后,余额宝服务会通过数据库去看一下该事件有没有进行执行。如果说已经执行了就会再触发确认消息的发送。结果就是支付宝系统会删除本地的事件记录
- 生产者数据的不丢失
- kafka 的 ack 机制,在 kafka 发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常的能够被收到。
- 消费者数据的不丢失
- 通过 offset commit 来保证数据的不丢失,kafka 自己记录了每次消费的 offset 数值,下次继续消费的时候,接着上次的 offset 进行消费即可
- 缺点:
- 因为 kafak 的分区缘故,没办法保证消息的顺序性
- 每台业务逻辑服上需要维护 kafak 进程
- 通过 sagas 模型来实现的
- sagas 模型实际上是一个长事务,它是一系列本地的有序事务,每个本地事务通过更新数据库发送消息来触发下一个本地事务
- 如果本地事务失败,sagas 会有序的执行补偿事务,来回滚刚才的操作
- 缺点
- 本地事务和补偿子事务都需要严格按照顺序执行
- 操作比较复杂,目前还没有框架来支持 sagas 的补偿模式