观点丨??基于异步通信的微服务分布式事务管理机制研究分析

文 / 中国人民银行清算总中心? 葛洪慧
观点丨??基于异步通信的微服务分布式事务管理机制研究分析文章插图
分布式系统在计算机科学理论中CAP定理指出 , 分布式系统的一致性、可用性和分区容错性只能满足三项中的两项 。 架构师在分布式系统的应用设计中 , 面临一致性和可用性问题时 , 往往会选择可用性 , 因为它直接影响到用户体验和客户流失 。 因而分布式系统的一致性问题成为分布式系统领域探索的热门问题 。
提到分布式系统的一致性问题 , 就会涉及事务 。 事务(Rransaction)是具有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)等属性特征(ACID)的一组相关操作 。
事务的ACID属性中的一致性和CAP定理的一致性是有区别的 。 事务的一致性是指事务不能破坏数据库的规则 , 比如数据库键值唯一 。 大量事务并发操作时 , 就像按某个顺序执行的结果一样 , 数据库的键值唯一性不被破坏 。 CAP定理的一致性 , 指分布式环境下所有节点得到的最新的数据副本是一样的 。 在分布式环境下各节点的事务并发操作时 , 就像按某个顺序执行的结果一样 , 任何节点得到的数据副本是一样的 。 所以事务的ACID属性里的一致性 , 在分布式环境下的事务有可能不一致 , CAP 定理里面提到的一致性是在分布式下环境下的一致性 , 是ACID一致性的更严格的子集 。
跨多个开放系统执行的事务称为分布式事务 。 X/Open分布式事务处理模型(X/Open XA)是分布式事务管理的事实标准 , XA使用两阶段提交来确保事务中的所有参与者都提交或回滚 , 能够保证分布式事务的ACID属性 。 实现了CAP定理提到的一致性问题 。
那么XA协议是否适合微服务技术架构呢?我们来看微服务架构的特征 。
微服务架构著名架构师Adrian Cockcroft把微服务架构定义为面向服务的架构 , 它们由松耦合和具有边界上下文的元素组成 。 这里的边界上下文可理解为可以用通用IDL(Interface Definition Language)定义的服务接口 , 服务、服务接口以及接口间通信构成微服务的体系架构 。 微服务架构以服务间松耦合、独立部署、技术独立演进、快速和可持续交付、良好的容错性和可重用性等等 , 近年来在分布式系统的应用技术架构选择中得到更多的关注 。
由于微服务架构以服务间松耦合为显著特征 , 而两阶段提交的每次操作均需服务同时在线协商 , 服务间耦合性较大 。 因此 , 基于两阶段提交的XA协议的分布式事务管理机制并不适合微服务架构的事务管理 。 同时 , 由于XA协议的同步协商特征 , 使得系统整体可用性和系统性能降低 。
实现原理目前 , Sagas是微服务体系架构中 , 管理多个服务数据操作 , 保持数据一致性 , 符合微服务架构特征的分布式事务管理的解决方案 。 它实际上是使用补偿性事务作为处理长交易的一种方法 。 把一个长交易分成多个子事务 , 每个事务Ti对应补偿事务 Ci 。 如果事务Tn+1失败 , 长交易的执行顺序为T1…Tn , Cn…C1 , 通过执行补偿事务来撤销每个已提交的子事务 , 从而中止长交易 。 当然 , 对数据库的读操作是不需要补偿事务的 。
Sagas的每个子事务Ti是本地事务 , 具有ACID属性 。 由于Sagas可能会看到其他 Sagas的部分执行结果 , 因此Sagas缺少隔离性 。 Sagas作为一个长交易序列 , 整体是具有ACD属性的 。
【观点丨??基于异步通信的微服务分布式事务管理机制研究分析】事务的隔离性分为不同级别 , 包括未提交读、提交读、可重复读和串行化 。 缺少隔离性会造成脏读等 。 由于Sagas缺少隔离性 , 那么需要通过增加相应的策略 , 比如可通过增加语义锁等对策 , 来保证缺少隔离性带来的一致性问题 。
下面以一种简化的转账业务 , 对基于异步通信方式的Eventuate? Sagas的开源架构分布式事务管理的实现方式和数据一致性保障机制进行分析 。
分布式事务管理机制分析简化的转账业务 , 服务A(TransReqService)为转账请求管理服务 , 服务B(TransDealService)为转账处理服务 , 两个微服务运行在不同的网络节点上 , 各自维护同一个数据库中不同的表(或本地数据库) 。 服务A接收到客户转账请求后 , 数据库中记录转账请求并通知服务B进行转账处理 , 根据收到的返回结果更新本地转账状态 。 服务B收到调用申请 , 完成转账业务处理 , 更新数据库账户信息 , 将处理结果返回服务A 。
Eventuate? Tram框架是通过Sagas方式解决微服务分布式系统的数据一致性管理问题的平台 。 提供了两种模式 , 一种是基于事件消息的事件编排模式 , 一种是基于命令消息 , 有核心协调器的命令协调模式 。 两种模式均支持基于异步消息的通信方式 , 可以采用消息代理 , 也可以不用 。 这里以消息代理方式分析 。