saga:支持编配型,异常时协调器可以启动补偿动作,竟然比编排型
在编配型Saga中,会有一个服务承担编配器或者协调器的功能:它会执行和跟踪跨多服务的Saga及其结果。编配器唯一的职责是管理Saga的执行。它会通过异步事件或者请求-响应的消息方式来与Saga中的各个参与方进行交互。最重要的是,它跟踪流程中每个步骤的执行状态——有时这也被称作Saga日志。
还是以下单出售股票为例,把order服务当作Saga协调器。order服务需要跟踪下单过程中每个步骤的执行情况。为了便于理解,将协调器类比为一种状态机:一系列的状态以及状态间的转换。协作方的每个响应都会触发协调器的状态发生变化,进而一步步推动协调器达到Saga的结果。
在编配式的Saga中,协调器负责在事务执行失败后启动合适的调解动作,来让受影响的实体恢复到有效且一致的状态。
假设market服务不能将订单提交到市场时,编配器会启动补偿动作:T1发起请求取消之前从客户那边收取的费用;T2向account transaction服务发起请求来撤销之前预留的股票;T3修改订单的状态来反映Saga的结果,如拒绝或者失败——这取决于业务逻辑(失败的订单是否要展示给客户或者重试)。对应地,编配器可以跟踪动作1和动作2的结果。
需要记住的是,补偿动作不都是即时生效的或者同时完成的。比如,如果手续费是从客户的信用卡中收取的,那么银行可能需要花一周的时间才会撤销这笔费用。
如果想要执行的操作会失败,那么补偿操作或者编配器自身同样可能会出现故障。我们在设计补偿操作时,就应该将其设计为可重试的并且没有意料之外的副作用(比如,退两次费用)的安全操作。最差情况下,在回滚过程中重复出现的故障会需要手动介入。全面的异常监控系统会能够发现这些场景。
优势
将Saga顺序性的业务逻辑集中到单个服务中,能够让开发者更加容易地分析和推断Saga的当前进展和结果,而且更加易于修改Saga的执行顺序,因为只需要修改调度器这一处地方。对应地,这种方式也简化了每个服务的工作,降低了这些服务所需要管理的状态的复杂度,因为业务逻辑都移到了协调器中。
不足
这种编配式Saga方案的风险就是将太多的业务逻辑移到协调器中。极端情况下,这会使得其他服务变得越来越“贫血”,每个服务都仅仅是把数据存储包装了一下,不再是那种自治的并且能够独立负责业务功能的服务。
许多微服务实践者更拥护点对点的编排方案,因为他们认为这种方案体现了微服务架构的目标“端点智能化,管道傻瓜化”。但是编配式方案在社区中正变得越来越普遍,特别是在开发一些执行时间比较长的交互时。
摘取自 摩根·布鲁斯和保罗·A.佩雷拉的《微服务实战》