[关闭]
@windwolf 2020-05-19T06:20:50.000000Z 字数 2173 阅读 285

Sailing的微服务化之路

Sailing 微服务


微服务的好处坏处就不多说了, 网上一找一片, 微服务化也是走向SaaS的必经之路, 那么就要想办法解决微服务所带来的问题. 对全顺所在领域来说, 微服务带来的问题主要有两个:

事务处理

总体来说, 在做服务切割的时候, 就应该考虑应用场景的事务性. 应该尽量避免跨服务的事务, 能用单机事务就用单机事务, 但跨服务事务是不可避免的. 跨服务事务主要有以下种套路:

我们对这些事务实现方式做一个比较:

事务类型 数据完整性 性能 业务侵入性 其他要求
本地事务 局部一致性
2PC/3PC 强一致性 数据源需支持XA接口.***
LCN 强一致性 需要独立的TxManager服务.
TCC 强一致性* 高*
消息队列 最终一致性 较高 中**

*需要针对每种业务场景分别编写Try/Confirm/Cancel
**需要订阅消息来更新状态, 对于复杂场景, 还需要通过消息订阅来处理事务补偿.
***很多现代数据库不支持基本的ACID,两阶段提交更无从谈起

从上表可知, 每种事务都有其某方面的优势和劣势, 因此也就有其适合的场景.

事务类型 应用场景
本地事务 事务无需跨服务. 能使用本地事务的尽量使用本地事务.
2PC/3PC 事务参与方较少, 参与方可用性很高.
LCN
TCC 能解决事务中预留业务资源问题.
消息队列 整个事务由发起方和跟随方组成, 跟随方完成与否不直接影响发起方事务, 或者由事务发起方可以决定事务提交还是回滚.*

*需要针对每种业务场景分别编写Try/Confirm/Cancel

如果从如何短平快地将Sailing迁移到微服务环境这个角度来看, 那么结果指向LCN. 因为:
- 强一致性分布式事务可以确保服务切分过程中, 架构无需调整.
- 代码侵入性低, 切换到分布式事务成本低.
- 性能可接收. 有测试报告表明, LCN方式在Spring Cloud下, 相比本地事务有大约21%的性能下降.
但这必定只是权益之计. 真正地解决方案还要继续展开探讨.

所有强一致性的方案都存在或多或少的性能问题, 因此需要放弃强一致性, 而考虑最终一致性. 虽然最终一致性是由PAC理论引出来的, 但它很多情况下是作为DDD的一部分来讨论的, 所以我们先来分析以下Sailing和DDD的关系.

DDD中有Entity->Aggregation->Domain这样三层构建块, Entity是数据的载体或者说表现形式; Aggregation是一组由强关联关系的Entity集合, 每个Aggregation都有一个AggregationRoot, 一个Aggregation内, Entity之间都是通过对象直接引用来关联的, 每个AggregationRoot都必须可以用id来索引, 一个Aggregation(包括AggregationRoot和其所关联的其他Entity)是作为一个基本单元操作的; Domain是一组Aggregation的集合, Aggregation之间都是通过id来引用.

拿客户订单系统做个例子: 客户信息是个Entity, 客户地址信息是个Entity, 订单是一个Entity, 订单明细也是一个Entity. 客户信息和客户地址信息是一个Aggregation, 客户信息是AggregationRoot, 客户信息直接引用客户地址信息的列表, 客户地址直接引用所属客户; 订单和订单明细构成一个Aggregation, 订单是AggregationRoot, 订单直接引用订单明细列表, 订单明细列表引用所属订单. 客户Aggregation和订单Aggregation构成一个客户订单Domain.

再看Sailing, Sailing中有Entity->Bill/BillType->Module这三个概念, 和DDD中的概念几乎一一对应; 各项特征也几乎全都满足, 唯一的区别是, Sailing并不硬性限制只能通过Root作为一个单元来查询Entity, 也允许直接查询子Entity, 但不推荐这么做. 查询部分后续章节展开讨论.

因此, 从构建块这个角度来看, Sailing符合DDD架构.

再从通信方式的角度入手来看看事务处理, DDD对事务没有明确的要求, 主要是根据业务场景来选择. 但我们通过对构建块的结构的分析可以总结出这么几点:

目前在Sailing中, Bill/BillType之间的通信主要通过BillTransformer和BillTracking. 如何迁移到消息订阅方式是个挑战.
例如一个单据提交, 大致过程如下:

  1. 单据保存.
  2. 验证规则验证
    1. 单据自身规则
    2. 工作流前置规则
      // 3. 节点规则
    3. 单据跟踪规则
  3. 发起工作流
  4. 执行工作流节点钩子
    1. 撤回时的生效保证.
    2. 单据跟踪反写.
    3. 节点是否允许撤回.
    4. 生效后发送通知下游.
    5. 撤回时的进程说明更新.
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注