Saga 状态机设计文档

概览

在不改变 Omega 和 Alpha 之间通信协议的前提下,基于 kafka 和 Akka FSM 实现事务消息的分布式处理,提升集群处理性能。

  • Omega 和 Alpha 之间的通信协议保持 gRPC 不变
  • Alpha 收到事务消息后写入 kafka,采用 globalTxId 作为分区条件,确保同一个完整事务的所有消息在消费端有序处理
  • Alpha 消费 kafka 中的事物消息,并创建 Saga Actor 对象实现事务状态的转换和跟踪

image-20190621084708897

事件定义

事件在 Omega 侧创建,并通过 gRPC 发送给 Alpha

名称缩写描述
SagaStartedEventEss全局事务开始
SagaEndedEventEse全局事务结束
SagaAbortedEventEsa全局事务失败,当Omega侧拦截到非超时类异常时将发送此事件
SagaTimeoutEventEst全局事务超时,当Omega侧拦截到请求出现网络超时、请求超时、全局事务自定义超时的时候Omega组件会中断请求线程并发送此事件
TxStartedEventEts子事务开始
TxEndedEventEte子事务结束
TxAbortedEventEta子事务失败
TxComponsitedEventEtc子事务补偿成功

状态机设计

状态机基于 Akka FSM 实现,基于Akka 的持久化和集群能力实现高可用

由于状态机的设计必须遵许已知的事件类型和顺序,而事件的发送又依赖于开发者对于 Omega 组件的使用,为了避免未知的情况出现而导致的不可控情况,本设计遵循以下约定

  • 状态机只处理已知的有序事件组合情况
  • 对于未知的事件组合情况统一将状态设置成 SUSPENDED 并结束
  • 对于 SagaTimeoutEvent 事件统一将状态设置成 SUSPENDED 并结束
  • 状态机内部会记录完整的事件记录以及状态转换记录,以便于问题的分析以及手动补偿

image-20190620150334083

状态定义

名称描述
IDEL空闲状态:Actor 创建后的初始化状态
READY就绪状态:收到全局务开始事件 SagaStartedEvent 后的状态
PARTIALLY_ACTIVE部分开始状态:收到了子事务开始事件 TxStartedEvent 后的状态
PARTIALLY_COMMITTED部分提交状态:收到了事务结束事件 TxEndedEvent 后的状态
FAILED失败状态:全局事务失败状态,当收到 TxAbortedEvent 或者 SagaAbortedEvent 事件满足进入此状态后将对所有已提交的子事务进行补偿,并在此状态等待所有 TxComponsitedEvent 收到后转换为 COMPENSATED 状态并终止。考虑到并行子事务的可能性,在此状态下收到 TxEndedEvent 事件后也将调用补偿方法
COMMITTED已提交状态:全局事务正常结束状态,所有子事物都已经提交
COMPENSATED已补偿状态:全局事务正常结束状态,所有已经提交的子事务补偿成功
SUSPENDED挂起状态:全局事务异常结束状态,当出现不符合预期的事件状态组合或者收到 SagaTimeoutEvent 事件时将进入挂起状态,设计挂起状态的目的是为了避免问题扩散,此时需要人工介入处理

状态转换表

状态转换表定义了事件与状态的转换关系