开发者社区 > 云原生 > 微服务 > 正文

[@小川游鱼][¥20]在微服务的架构中,一个业务涉及到调用多个其他微服务,如何保证多个微服务间的事务一致性?

问题来自Java技术沙龙的陈启辉
Java线下沙龙报名链接:https://yq.aliyun.com/activity/796

展开
收起
李博 bluemind 2018-12-07 11:45:48 5149 0
1 条回答
写回答
取消 提交回答
  • 阿里云问答专家、阿里云认证云计算工程师、Java研发工程师

    最终都必须保证数据一致性,至于中间具体采用哪种模式,还是需要根据具体的业务逻辑来选择:

    1、可靠事件模式

    可靠事件模式属于事件驱动架构,当某件重要事情发生时,例如更新一个业务实体,微服务会向消息代理发布一个事件。消息代理会向订阅事件的微服务推送事件,当订阅这些事件的微服务接收此事件时,就可以完成自己的业务,也可能会引发更多的事件发布。

    这个过程可能导致出现不一致的地方在于:某个微服务在更新了业务实体后发布事件却失败;虽然微服务发布事件成功,但是消息代理未能正确推送事件到订阅的微服务;接受事件的微服务重复消费了事件。

    可靠事件模式在于保证可靠事件投递和避免重复消费,可靠事件投递定义为(a)每个服务原子性的业务操作和发布事件(b)消息代理确保事件传递至少一次。

    避免重复消费要求服务实现幂等性,如支付服务不能因为重复收到事件而多次支付。

    2、补偿模式

    为了描述方便,这里先定义两个概念:

    业务异常:业务逻辑产生错误的情况,比如账户余额不足、商品库存不足等。
    技术异常:非业务逻辑产生的异常,如网络连接异常、网络超时等。

    补偿模式使用一个额外的协调服务来协调各个需要保证一致性的微服务,协调服务按顺序调用各个微服务,如果某个微服务调用异常(包括业务异常和技术异常)就取消之前所有已经调用成功的微服务。

    补偿模式建议仅用于不能避免出现业务异常的情况,如果有可能应该优化业务模式,以避免要求补偿事务。如账户余额不足的业务异常可通过预先冻结金额的方式避免,商品库存不足可要求商家准备额外的库存等。

    我们通过一个实例来说明补偿模式,一家旅行公司提供预订行程的业务,可以通过公司的网站提前预订飞机票、火车票、酒店等。

    假设一位客户规划的行程是,(1)上海-北京6月19日9点的某某航班,(2)某某酒店住宿3晚,(3)北京-上海6月22日17点火车。在客户提交行程后,旅行公司的预订行程业务按顺序串行的调用航班预订服务、酒店预订服务、火车预订服务。最后的火车预订服务成功后整个预订业务才算完成。

    如果火车票预订服务没有调用成功,那么之前预订的航班、酒店都得取消。取消之前预订的酒店、航班即为补偿过程。
    需要注意的是酒店的取消预订、航班的取消预订同样不能保证一定成功,所以补偿过程往往也同样需要实现最终一致性,需要保证取消服务至少被调用一次和取消服务必须实现幂等性。

    我们应该尽可能通过设计避免采用补偿方式,比如上面的例子中,在预订火车票失败的时候可以提示客户更改其他的时间。

    3、TCC模式(Try-Confirm-Cancel)

    一个完整的TCC业务由一个主业务服务和若干个从业务服务组成,主业务服务发起并完成整个业务活动,TCC模式要求从服务提供三个接口:Try、Confirm、Cancel。

    第一阶段:主业务服务分别调用所有从业务的try操作,并在活动管理器中登记所有从业务服务。当所有从业务服务的try操作都调用成功或者某个从业务服务的try操作失败,进入第二阶段。

    第二阶段:活动管理器根据第一阶段的执行结果来执行confirm或cancel操作。如果第一阶段所有try操作都成功,则活动管理器调用所有从业务活动的confirm操作。否则调用所有从业务服务的cancel操作。

    需要注意的是第二阶段confirm或cancel操作本身也是满足最终一致性的过程,在调用confirm或cancel的时候也可能因为某种原因(比如网络)导致调用失败,所以需要活动管理支持重试的能力,同时这也就要求confirm和cancel操作具有幂等性。

    2019-07-17 23:18:42
    赞同 展开评论 打赏

为微服务建设降本增效,为微服务落地保驾护航。

相关电子书

更多
微服务治理技术白皮书 立即下载
微服务与Serverless 立即下载
EDAS4.0 助力企业一站实现微服务架构转型与 K8s 容器化升级 立即下载