此文翻译自msdn,侵删。

原文地址:https://msdn.microsoft.com/en-us/library/jj591569.aspx

Process Managers, Coordinating Workflows, and Sagas

分清术语

saga这个名词通常被用在CQRS的讨论中,它是指一段在限定上下文(bounded contexts )和聚合(aggregates)之间起协作和路由(coordinates and routes )消息作用的代码。然而,在这个指南中我们更喜欢用Process manager这个词语去表示saga。有两个原因:

  • 之前已经有了一个广泛被熟知的名词saga,这个saga和CQRS中的saga有着不同的含义。
  • process manager 是一个更合适用来描述saga在这里扮演角色的名词。

虽然saga经常在CQRS模式中见到,然而它已经在这之前有了其自己的含义。在这个指南中我们使用process manager 以便于和saga之前的含义区分开来。

saga,与分布式相关,最早被定义在Hector Garcia-Molina和Kenneth Salem的论文"Sagas"中。这篇论文提出了一个saga机制来作为分布式事务的替代品以解决长时间运行的分布式事务(long-running process)的问题。这篇论文认为业务过程经常由很多步骤组成,每个步骤都涉及一个事务,如果将这些事务组成一个分布式事务,就可以实现总体一致(overall consistency )。然而在长时间运行的分布式事务中,使用分布式事务会影响效率和系统的并发处理能力,因为在执行分布式事务的时候会有锁产生。

注意:

saga通过确保每一个业务过程都有修正事务(compensating transaction)来减少了系统对分布式事务的依赖。在这种方式下,如果业务过程遇到了错误的情况并且无法继续,它就可以执行修正事务来修正已经完成的步骤。这种在业务流程中去撤销已经完成的工作的方式保证了系统的一致性。

尽管我们已经选择使用process manager这个名词了,sagas仍然在实现CQRS系统中的限定上下文中扮演着一些角色。比如说,你可能会希望看到process manager在一个限定上下文中的聚合中路由消息,你也可能会希望看到saga管理一个在多个限定上下文中长时间运行的业务过程。

以下的几个部分描述了process manager,这个是我们在我们的CQRS之旅项目中对saga的定义。

注意:

在使用process manager之前,我们的团队曾经有一段时间使用coordinating workflow 这个名词。这种模式在Gregor Hohpe 和 Bobby Woolf的书"Enterprise Integration Patterns”中有所描述。

Process Manager

这一节概括了我们的process manager定义。在描述process manager之前有一段简短的关于CQRS使用消息(messages)在聚合和限定上下文中通讯的回顾。

消息和CQRS

当你实现CQRS模式的时候,你可能会思考两种类型的消息如何在你的系统中交换数据:command和事件。

command是一种请求,他们请求系统去执行一个任务或者动作。例如“预定两个X会议的座位”或者“把演讲者Y分配到Z室”。command通常只被一个接收者执行一次。

事件是一种通知,他们告诉系统中一些它们感兴趣的部分:有一些事情已经发生了。例如“支付被拒绝了”或者“产生了X类型座位”。注意他们使用的是过去式——事件已经被产生并且可能有许多订阅者。

通常来说,command被发送到同一个限定上下文中。事件的订阅者可能在它们发布的限定上下文中,或者在其他的限定上下文中。

引用指南中的"A CQRS and ES Deep Dive"章节详细地介绍了这两种不同的消息类型。

process manager是什么?

在一个复杂系统建模中,你可能已经使用了聚合和限定上下文,他们可能有一些包含了很多聚合的业务过程,或者在一个限定上下文中有很多的聚合。在这个业务过程中,许多不同类型的消息被交换。例如,在一个会议管理系统中,有一个预定座位的业务过程包含了order聚合,一个reservation聚合和一个payment的聚合。他们必须结合起来以保证一个客户能够完成预定交易。

图1表示了一个简化的消息场景,在这个场景中这些聚合互相交互来完成这个订单。数字表明了消息流转的顺序

注意:

这个图并没有展示这个实现如何处理订单

图1

不使用process manager的订单处理过程

在图1展示的例子中,每一个聚合都向与流程下一步相关的聚合发送一个相应的command。Order聚合首先发送一个MakeReservation 的command给Reservation聚合来预定客户需要的位置。在座位被预定之后,Reservation聚合就会发送一个SeatsReserved事件通知Order聚合,然后Order聚合就会向Payment聚合发送一个MakePayment的command。如果付款成功,Order聚合就会生成一个OrderConfirmed的事件通知Reservation聚合确定座位已经被预定,并且通知客户订单完成。

图2

使用process manager 的订单业务过程

图2中展示的例子描述了和图1一样的业务过程,但是这次使用了process manager 。现在,这些消息通过process manager 来管理,而不是聚合根直接向另外一个聚合跟发送消息。

这样明显地将整个过程复杂化了:这个过程现在多了一个对象(process manager )和一些消息。然而这些都是有益的。

首先,聚合不再需要知道流程的下一步是什么。之前Order聚合必须知道在完成预定之后,它需要尝试着去向Payment 聚合发送一个消息来完成一个支付。现在它只要报告一个订单已经生成就可以了。

然后,这个消息流的处理被限定在一个地方,那就是process manager,而不是分散到这些聚合中。

在一个类似于图1或者图2的简单业务过程中,这么做的好处很小。然而如果你有一个包含六个聚合和数十个消息的业务过程,这么做的好处就很明显了。这尤其在一个系统中某个业务容易发生变化的部分中更加明显:在这种情况下,业务的改变更容易被限定在有限的对象中。

在图3中,为了描述这个观点,我们向其中引入了一个等待列表。如果一些作为预定请求不能被预定,那么系统就会把这些请求添加到一个等待列表中。在发布SeatsReserved 事件(报告还有多少座位可以被预定)功能的基础上,我们为Reservation 聚合新增了一个发布SeatsNotReserved 事件的功能去报告还有多少座位不可以被预定。process manager可以向WaitList 聚合中发送一个command来添加一个待处理请求。

图3

包含一个process manager 和一个等待列表的订单业务过程

很重要的一点需要注意,process manager本身不包含任何业务逻辑。它仅仅路由消息,或者在一些情况下转换消息类型。例如,当它接受到一个SeatsNotReserved事件,它发布一个AddToWaitList的command。

我应该什么时候使用process manager?

有两个重要的使用process manager的原因:

  • 当你在一个限定上下文使用很多事件和command的时候,难以把聚合之间的交互(point-to-point interactions between aggregates)统一管理。
  • 当你想要在限定上下文中更容易地去修改消息的路由。一个process manager会提供一个单独的路由定义位置。

我应该什么时候不使用process manager?

下面列了不适用process manager的原因:

  • 如果你的限定上下文仅包含很少数量的使用少量的消息的聚合类型。
  • 你不可以在你的领域中使用process manager来实现任何业务逻辑。业务逻辑应该在相应的聚合类中。

sagas和CQRS

尽管我们在之前的章节中已经选择了process manager这个名词,saga仍然在使用CQRS模式的系统中扮演一定的角色。比如说,你可能会希望看到process manager在一个限定上下文中的聚合中路由消息,你也可能会希望看到saga管理一个在多个限定上下文中长时间运行的业务过程。

saga中的saga(A Saga on Sagas)的更多相关文章

  1. 《微服务架构设计模式》读书笔记 | 第4章 使用Saga管理事务

    目录 前言 1. 微服务架构下的事务管理 1.1 分布式事务的挑战 1.2 一个Saga的示例 1.3 Saga使用补偿事务来回滚所作出的改变 2. Saga的协调模式 2.1 两种Saga协调模式 ...

  2. 让你的saga更具有可伸缩性(Scaling NServiceBus Sagas)

    https://lostechies.com/jimmybogard/2013/03/26/scaling-nservicebus-sagas/ 当我们使用NServiceBus sagas (pro ...

  3. 使用事件和 CQRS 重写 CRUD 系统

    使用事件和 CQRS 重写 CRUD 系统 https://msdn.microsoft.com/zh-cn/magazine/mt790196.aspx https://github.com/mem ...

  4. [React] 14 - Redux: Redux Saga

    Ref: Build Real App with React #14: Redux Saga Ref: 聊一聊 redux 异步流之 redux-saga  [入门] Ref: 从redux-thun ...

  5. react系列(六)Redux Saga

    在Redux中常要管理异步操作,目前社区流行的有Redux-Saga.Redux-thunk等.在管理复杂应用时,推荐使用Redux-Saga,它提供了用 generator 书写类同步代码的能力. ...

  6. Saga的实现模式——进化(Saga implementation patterns – variations)

    在之前的几个博客中,我主要讲了两个saga的实现模式: 基于command的控制者模式 基于事件的观察者模式 当然,这些都不是实现saga的唯一方式.我们甚至可以将这些结合起来. 发布者——收集者 回 ...

  7. 分布式事务:Saga模式

    1 Saga相关概念 1987年普林斯顿大学的Hector Garcia-Molina和Kenneth Salem发表了一篇Paper Sagas,讲述的是如何处理long lived transac ...

  8. ENode 1.0 - Saga的思想与实现

    开源地址:https://github.com/tangxuehua/enode 因为enode框架的思想是,一次修改只能新建或修改一个聚合根:那么,如果一个用户请求要涉及多个聚合根的新建或修改该怎么 ...

  9. enode框架step by step之saga的思想与实现

    enode框架step by step之saga的思想与实现 enode框架系列step by step文章系列索引: 分享一个基于DDD以及事件驱动架构(EDA)的应用开发框架enode enode ...

随机推荐

  1. CF 983B 序列函数

    CF 983B 序列函数 一道本校神仙wucstdio出的毒瘤签到题. 题意: 给你一段序列,求出它们的最大异或和. 解法: 其实这道题并不很难,但读题上可能会有困难. 其实样例我是用Python 3 ...

  2. SQL SERVER 断开所有连接(转)

    通过sql server management studio对数据进行管理,比如数据库改名等,经常遇到有正在运行的连接,以致无法操作,这时候断掉所有的连接很有必要.代码如下:(会断掉某个库的所有连接, ...

  3. PL/SQL开发中动态SQL的使用方法

    一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DDL语句及系统控制语句,可以通过使 ...

  4. IIS部署asp.net MVC 出现错误 403.14-Forbidden解决办法

    可能性一: <system.webServer>   <validationvalidateIntegratedModeConfiguration="false" ...

  5. LoadRunner中的随机数

    LoadRunner中的随机数 Action() { int i; ]; srand(time(NULL)); i=rand()%; lr_save_datetime("%m%d%H%M%S ...

  6. 本机ip和127.0.0.1的区别

    简介 连接上因特网的每一台计算机都会有一个IP地址, 在linux下可以使用命令ifconfig来查看本机的ip地址(windows为ipconfig), 比如我当前电脑的ip地址为192.168.0 ...

  7. 牛客网 桂林电子科技大学第三届ACM程序设计竞赛 C.二元-K个二元组最小值和最大-优先队列+贪心(思维)

    链接:https://ac.nowcoder.com/acm/contest/558/C来源:牛客网 小猫在研究二元组. 小猫在研究最大值. 给定N个二元组(a1,b1),(a2,b2),…,(aN, ...

  8. OneDrive 开机启动设置失效如何处理?

    问题现象: 『设置里勾选了开机启动onedrive,但是重启电脑勾选就没了,重新勾选没用,一重启就没了』 win10的onedrive无法开机启动 - Microsoft Community 处理方式 ...

  9. 图解在Eclipse中如何上传项目到svn

    方法/步骤 1.在Eclipse中新建project,如下图所示: 2.右键project --> team --> share project,如下图所示: 3.选择repository ...

  10. OpenVAS漏洞扫描基础教程之连接OpenVAS服务

    OpenVAS漏洞扫描基础教程之连接OpenVAS服务 连接OpenVAS服务 当用户将OpenVAS工具安装并配置完后,用户即可使用不同的客户端连接该服务器.然后,对目标主机实施漏洞扫描.在本教程中 ...