关于 CAP 理论什么的在这里就不说了, 主要说应用到业务中的问题.
大概的架构是: 服务(包括数据与基础方法) -> 业务(调用服务完成用户的需求) -> 用户(前端)
在多项服务之间, 需要保持数据一致性.
保持数据一致性的三种做法:
- 事务 (2PC/3PC, 例如 postgresql PREPARE TRANSACTION)
- 回滚 (有人称为 Saga, 例如 CouchDB _rev, 或凭证式数据结构)
- 消息 (例如 kafka, 或 AWS SNS + Lambda)
以上做法从一致性上依次弱化.
以上做法也有各自的局限, 需要额外的工作:
- 事务. 如果程序意外终止, 可能造成事务堆积, 很可能持有锁导致后续业务无法进行, 需要及时处理.
- 回滚. 如果程序意外终止, 可能造成数据没有被回滚, 需要处理.
- 消息. 如果消息没有被处理成功, 需要处理.
一个前端使用的新增订单 API 设计可能涉及如下服务:
库存需要使用分布式事务来锁库存以避免瞬发下单导致的负库存的情况.
同样, 积分也要锁以避免同一人同时使用积分导致的积分不足.
订单与凭证一般都会写成功, 但订单服务返回的信息如订单号要及时返回给前端, 而凭证不需要.
最终在一个新增订单的 API 中, 是这样使用服务的:
- 首先同时异步调用三个服务: 1. 修改库存 (组成事务), 2. 扣除积分(组成事务), 3. 创建订单(可回滚).
- 如果 1, 2 均 执行成功, 则完成事务, 写入消息队列以添加凭证.
- 如果 1, 2 有任一不成功, 则取消事务, 回滚订单.