https://lostechies.com/jimmybogard/2013/03/11/saga-implementation-patterns-observer/

侵删。

NServiceBus sagas 是一个Process Manager pattern的实现,在实现的时候经常使用它的一两种主要形式。虽然各有差别,但总的来说saga的实现也就总是那几种。

第一种是观察者模式。作为一个观察者,saga通过响应事件来协调业务:

观察者有一些特性:

  • 消息以事件的形式接收
  • saga并不控制消息接收的顺序

因为saga不控制消息的顺序并且这些消息都是事件,所以saga是一个观察者。它自身不影响外部服务,但是它观测每个服务发布的服务。

观察者其他的一个有趣的特性是:它的职责是在它接受到所有事件之后它要协调整个业务,类似于这样:

这个和Scatter/Gather pattern有些相似。saga需要保证自身能够追踪收到的消息。除了接收消息,它还会记录已经收到的消息和检查是否需要进行到下一步的所有相关消息都已经收到。

这个一个简单的工作流模式, 但要注意的是它不知道什么消息会以什么顺序收到。

为了看这个模式如何运作,我们可以参考一个真实世界的场景来看看这种模式的工作方式。

快餐店的消息流转——麦当劳

学习分布式系统的一个有趣的事情就是它的应用例子实际上就在我们生活之中。一个在真实世界中的很好的saga观察者模式的例子就是麦当劳的订单处理过程。

客户订单中食物的准备工作不是按照一个固定的顺序来的。麦当劳有很多的工作台,这些工作台是相对独立的。在一个订单中,我们可能需要以下的食物:

  • 三明治
  • 饮料
  • 色拉
  • 薯条
  • 咖啡

呃,当然还有其他的东西。每一个工作台都有他们自己的工人,每个工人都有他们自己的工作队列。一个典型的订单处理过程看起来应该是这样的:

整个流程从客户下一个订单(1)开始。如果这个订单被接受(麦当劳收到钱了),一个事件就被广播到所有与订单相关的食品准备工作台(2)。每个工作台上面都有一个屏幕,就像一个待完成的工作队列。

只有与这个工作台相关的订单信息展示在屏幕上面。如果订单里面没有薯条,那么制造薯条的工作台就不会有任何关于这个订单的信息。

每个工作台的工作都和其他工作台的工作相独立。制造薯条的工作台就不需要制造饮料工作台的信息来完成工作。

当每个工作台都完成各自的工作之后,他们把食物送到柜台(3)——在那里,每个订单都被分别装在各自的托盘里面。每一个成食物制作的员工都要弄清楚他做好的食物应该放在哪个托盘里面——可以根据订单号来判断。在每个工作台的屏幕上,订单都会根据订单号分开,这样每个工作台都能区分每个订单。

每当一个工作台把准备好的食物放到托盘的时候,员工就会检查托盘上的所有食物有没有完全准备好。这个动作会在每一个食物放到托盘上面的时候完成,我们必须重复地检查是否订单上的食物已经准备好。并没有人专门负责这个检查工作——每个完成食物制作的员工应该完成这种检查。

一旦一个员工确定订单上的食物都准备好了,他们就会呼叫订单号然后客户就会过来把托盘拿走(4)。

在用NServiceBus实现saga之前,我们已经在现实世界中观察saga是怎么运行的了(虽然我们从来不这样称呼快餐店的这种模式叫saga)。

优点和缺点

和其他模式一样,这种模式也有一些优点和缺点。麦当劳使用这种模式就是为了最大化它处理订单的效率,但是并不是所有的快餐服务都使用这种模式。他的优点在于:

  • 每一个员工都和其他员工并行工作,提高他们总体的效率
  • 每个员工都和其他员工独立,并且和其他步骤无耦合
  • 我们可以很容易地添加额外的流程或者员工(麦当劳餐厅可以添加咖啡这种服务,但是不改变他们的总体订单处理模式)

然而这个模式也有一些缺点:

  • 引入了资源的争夺问题。我们不能让两个员工在同时往同一个托盘里面放食物——因为没有足够的空间。托盘/saga变成整个系统的阻塞点(choke point )——并且我们很难扩展这个空间。
  • 每一个步骤都要检查看看saga是否完成。这个就引入了额外的业务逻辑去检查什么事件已经完成和整个saga是否已经完成。

下次你去快餐店用餐的时候,看看他们是否是按照这种方式工作的。在一个每个订单生成步骤都独立的快餐店,他们都认为这种处理订单的方式是最有效率的:)

Saga的实现模式——观察者(Saga implementation patterns – Observer)的更多相关文章

  1. Saga的实现模式——控制者(Saga implementation patterns – Controller)

    https://lostechies.com/jimmybogard/2013/03/14/saga-implementation-patterns-controller/ 之前的文章中我们介绍了观察 ...

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

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

  3. [Design Patterns] 03. Behavioral Patterns - Observer Pattern

    前言 参考资源 Ref: 史上最全设计模式导学目录(完整版) 观察者模式-Observer Pattern[学习难度:★★★☆☆,使用频率:★★★★★] 对象间的联动——观察者模式(一):多人联机对战 ...

  4. 《Language Implementation Patterns》之 增强解析模式

    上一章节讲述了基本的语言解析模式,LL(k)足以应付大多数的任务,但是对一些复杂的语言仍然显得不足,已付出更多的复杂度.和运行时效率为代价,我们可以得到能力更强的Parser. Pattern 5 : ...

  5. 局部二值模式(Local Binary Patterns)纹理灰度与旋转不变性

    Multiresolution Gray Scale and Rotation Invariant Texture Classification with Local Binary Patterns, ...

  6. .Net Core自实现CLR异步编程模式(Asynchronous programming patterns)

    最近在看一个线程框架,对.Net的异步编程模型很感兴趣,所以在这里实现CLR定义的异步编程模型,在CLR里有三种异步模式如下,如果不了解的可以详细看MSDN 文档Asynchronous progra ...

  7. Javascript编程模式(JavaScript Programming Patterns)Part 2.(高级篇)

    模块编程模式的启示(Revealing Module Pattern) 客户端对象(Custom Objects) 懒函数定义(Lazy Function Definition) Christian  ...

  8. Javascript编程模式(JavaScript Programming Patterns)Part 1.(初级篇)

    JavaScript 为网站添加状态,这些状态可能是校验或者更复杂的行为像拖拽终止功能或者是异步的请求webserver (aka Ajax). 在过去的那些年里, JavaScript librar ...

  9. 《Language Implementation Patterns》之 解释器

    前面讲述了如何验证语句,这章讲述如何构建一个解释器来执行语句,解释器有两种,高级解释器直接执行语句源码或AST这样的中间结构,低级解释器执行执行字节码(更接近机器指令的形式). 高级解释器比较适合DS ...

随机推荐

  1. AngularJs学习——实现列表内容项的增加删除

    效果截图: 说明:引入bootstrap.min.css样式库和angular.min.js的静态资源库,实现列表内容的增加和删除操作. AngularJS代码: <script src=&qu ...

  2. Struts2 利用拦截器 interceptor 控制登陆和访问权限

    最近学习了Struts2的登录和权限控制用到的是拦截器,需要在struts.xml中配置,每个action都默认的继承defaultStack,如果你用了别的拦截器,还需要手动引入defaultSta ...

  3. oracle中函数

    一:前言 最近决定每天都把知识点总结下,然后每个星期把知识点在进行分类发表日志. 二:The Question (1):在oracle中进行年龄的计算,知道出生日期进行计算后截取,本来是一个很简单的函 ...

  4. Dom4j解析语音数据XML文档(注意ArrayList多次添加对象,会导致覆盖之前的对象)

    今天做的一个用dom4j解析声音文本的xml文档时,我用ArrayList来存储每一个Item的信息,要注意ArrayList多次添加对象,会导致覆盖之前的对象:解决方案是在最后将对象添加入Array ...

  5. Bzoj3441 乌鸦喝水

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 258  Solved: 97 Description [题目背景]     一只乌鸦在自娱自乐,它在面 ...

  6. 【CF1023E】Down or Right(交互,贪心)

    题意: n<=500 思路:From https://blog.csdn.net/csdnjiangshan/article/details/81813227 #include<cstdi ...

  7. Python小程序之动态修改Haproxy配置文件

    需求如下: 1.动态的查询添加删除haproxy节点信息 2.程序功能:add(添加).Del(删除).Query(查询) 3.添加时实例字符串为:  {'backend': 'www.oldboy. ...

  8. Python3 安装xlrd、xlwt、xlutils

    Python版本3.4,装xlrd和xlwt和xlutils的时间:2017-09-07. 安装xlrd.xlwt.xlutils很简单,直接[pip install xlrd].[pip insta ...

  9. TCP的三次握手和四次挥手+TCP和UDP的区别

    TCP的三次握手: LISTEN:表示服务器端的某个socket处于监听状态,可以接收连接了. SYN_SENT:当客户端SOCKET执行connect连接时,它首先发送syn报文,随即会进入到此状态 ...

  10. Java坦克大战 (七) 之图片版

    本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...