在分布式系统中, 一个功能被拆分成多个具有单一功能的子模块, 一个流程就会有多个服务模块组合实现, 数据可能会出现不一致的问题, 但是有时候我们不需要实时的保持一致, 只要我们能保证最终一致性即可.
下面介绍几个常见的保证最终一致性的模式:
查询模式
任何服务都提供一个查询接口, 用来向外部输出操作执行的状态. 调用方根据查询接口得知服务执行状态, 根据不同状态做不同的处理操作.
每一个操作都需要有唯一的请求流水号, 也可以提供批量查询接口.
比如: 支付宝的资金冻结接口与资金操作查询接口. 支付接口 (可能会出现支付成功与支付失败) 与支付状态查询接口.
异步确保模式
异步确保模式是补偿模式的一个典型案例, 经常应用到使用放对响应时间要求不太高的场景中, 有时候执行方无法立刻返回结果, 先告知业务方等待, 在执行成功的时候再异步通知业务方执行成功, 不过业务方在调用的时候需要指定回调的 URL, 如果回调失败, 记录失败状态, 等定时任务再次进行回调, 直到成功为止.
关键: 操作入库, 定时任务捞取未完成任务进行补偿.
image
定期校对模式
系统再没有达到一致之前, 系统的状态可能是不一致的, 需要补偿操作来达到最终的一致性目的, 但是如何发现需要补偿的操作呢?
在操作主流程中的系统间执行校对操作, 可以在事后异步的批量校对操作的状态, 如果出现不一致的操作则进行补偿. 定期校对的一个关键是分布式系统中需要有一个自始至终唯一的 ID.
生成方式的话有很多项目可以做到. 参考生成全局唯一 ID 的 3 个思路 https://juejin.im/entry/57fe37eeda2f60004fb45723
定期校对模式多应用于金额系统中, 金融系统由于涉及资金安全, 需要保证准确性, 所以需要多重的唯一性保证机制. 包括商户对账, 现金对账, 财务对账等.
最后
在系统对一致性没有那么及时, 那么强的要求情况下, 我们可以使用上面的方式来保证最终一致性, 有时候我们可能会引入 MQ 来进行完全的解耦.
参考
《分布式服务架构 - 原理, 设计与实践》
《MQ 文集》
生成全局 ID 的思路 https://juejin.im/entry/57fe37eeda2f60004fb45723
来源: http://www.jianshu.com/p/35580ae15897