背景
你已经使用 database ber service 模式。每个service拥有自己的database。一些业务事务会跨越多个service,所以你需要来确保data consistency。例如,假设你正在构建一个电子商务网站,这个网站的用户的会有一个最大欠款限制,应用程序必须确保一个新订单不能超过用户的最大前款限制,但是orders表和customers表不在同一个数据库,所以应用程序不能简单的使用本地的ACID事务。
难题
怎么确保跨越多个service的数据一致性
驱动力
2pc(两阶段提交)不是一个好的选择
解决方案
把跨越多个service的每一个单独的事务实现成saga模式。一个saga是由local transaction组成的序列。每个local transaction更新本地数据库,然后发布一个message 或者event来触发下一个事务。如果有一个本地事务失败了,saga就会执行一系列的补偿事务来回滚之前的事务所做的修改。
saga模式有如下两种协作方式。
Choreography(编排)--每个本地事务发布domain event来触发别的service的local transaction.
Orchestration --有一个orchestrator 对象来告诉参与者执行哪一个事务。
Example: Choreography-based saga
一个电子商务网站使用choreography-based saga 来创建一个order。
- order service创建一个处于pending 状态的order,然后发布一个 ordercreated event
- customer service接受到ordercreated event ,然后为订单冻结金额。然后customer service 发布一个creait reserved event 或者creait limit exceeded event(如果账户的金额不够的话)
- order service接受到creait reserved event或者creait limit exceeded event,然后将订单状态修改为approved 或者cancelled
Example: Orchestration-based saga
这是一个使用Orchestration-based saga 模式来创建一张order的例子
- order service 创建一个order,设置order为pending 状态,然后在创建一个create order saga对象
- create order saga对象发送一个reserve credit reserved命令到customer service
- customer service尝试来为这张order 预留金额,然后返回一个应答
- createordersaga接受customer service返回的应答,然后返回一个ApprovedOrder或者RejectedOrder命令给order service
- order service将订单状态改成approved或者rejected
结果
saga模式有如下好处
- 不适用分布式事务来确保微服务的数据一致性
saga模式的缺点
- 编程模型太复杂。例如,开发人员必须设计能够回滚的补偿事务
需要解决的问题
- 为了确保可靠性,一个service必须atomically 的更新数据库,然后发布一个message/event。不能够使用传统的分布式事务机制来横跨database和message broker。