文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

一个微服务完成工作的一个业务单元。在大多数情况下,一个事务的范围就是工作的一个业务单元;因此,事务被自动包含在一个服务里。例如,一个“借记储蓄银行账户”操作可以被原子化,而且事务完整性可以确保这个操作在服务的范围内。

然而,也许有业务场景需要你运行跨多个服务的多个工作业务单元,这些工作单元是由不同管辖范围的不同的团队编写的。因为这样业务流程跨越多个服务的边界,确保事务完整性就变成了一个挑战。有多种策略可以应对这一挑战。 

第 1 段(可获 2 积分)

以我们都很熟悉的在线“信用卡还款”作为一个具体的例子, 还款需要两个操作的编排配合,“借记储蓄银行账户”和“信用卡账户”是由不同的管辖范围来处理的。在这种情况下,“信用卡还款”是一个跨两个服务的复合操作。储蓄借记和信用还贷操作应该同时发生或同时不发生。因此这给经典架构提出了一个挑战:我们要如何确保跨越了多个分布式服务执行的操作的事务完整性。

第 2 段(可获 2 积分)

我们首先会想到采用通过复合服务“信用卡还款”协调的分布式事务作为一种策略。然而,分布式服务在扩展性和稳定性上存在问题,例如可能会导致死锁,因此是不被推荐的。

补偿事务

一个更可行的策略是让“信用卡还款”的两个操作独立地执行。如果复合服务在储蓄借记操作完成后检测到信用还贷的操作失败,它会通过发送一个等价的贷方分录(credit entry)回滚储蓄账户的操作。这个贷方分录就是一个补偿事务。

第 3 段(可获 2 积分)

 Compensating Transaction

然而,也可能会有使用补偿策略反而影响事务完整性的场景。其中的一个场景就是在储蓄借记的操作执行完毕之后,信用还贷的操作执行开始之前,复合服务挂掉了。多种模式可以用来处理这种事务中间的失败。下面我们讨论一下这三种模式。

  • 状态仓库
  • 传送名单(Routing Slip)
  • 流程管理器

状态仓库

复合服务在一个状态仓库记录了所有的状态改变。如果复合服务挂了,状态仓库可以用来找到和恢复不完整的事务。

 State Store

第 4 段(可获 2 积分)

传送名单(Routing Slip)

另一个常用的有弹性的方法是使复合的“信用卡还款”异步操作。复合服务在传送名单中用两个请求命令(一个给储蓄账户的指令和一个给信用账户的指令)创建了一个信息。这个信息从传送名单被发送到借记储蓄服务。借记储蓄服务执行第一个命令,并在将信息交给完成信用还贷操作的信用服务之前丰富传送名单。如果中间发生了失败,这个信息会被传送到错误队列,复合服务可以在有需要时从错误队列查看状态、错误状态和补偿措施。

Routing Slip

流程管理器

传送名单的可替代方法是流程管理器,流程管理器监听储蓄借记和信用还贷操作的产生的事件,决定补偿还是完成事务。

第 5 段(可获 2 积分)

在相同的限定上下文内的折叠操作

举另一个例子, 两个储蓄账户间的金额转移可以通过调用两次“储蓄账户”微服务的传统方式完成,即一次操作针对起点的账户的借记,另一次操作针对终点的账户的贷入。这种方式在事务处理上的考虑和上面所述的是相似的。 然而,在这种情况下,由于借记和贷入操作都在“储蓄账户”的相同管辖范围内,“账户金额转移”逻辑可以只在执行借记和贷入操作的同一的微服务里面执行。这简化了事务处理的边界。

总结

至此,我们讨论了牵涉到微服务时处理事务的不同模式。根据你的使用案例,你可以从上面的选择中选出最好的方法。

第 6 段(可获 2 积分)

文章评论