Saga的实现模式——观察者(Saga implementation patterns – Observer)
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)的更多相关文章
- Saga的实现模式——控制者(Saga implementation patterns – Controller)
https://lostechies.com/jimmybogard/2013/03/14/saga-implementation-patterns-controller/ 之前的文章中我们介绍了观察 ...
- Saga的实现模式——进化(Saga implementation patterns – variations)
在之前的几个博客中,我主要讲了两个saga的实现模式: 基于command的控制者模式 基于事件的观察者模式 当然,这些都不是实现saga的唯一方式.我们甚至可以将这些结合起来. 发布者——收集者 回 ...
- [Design Patterns] 03. Behavioral Patterns - Observer Pattern
前言 参考资源 Ref: 史上最全设计模式导学目录(完整版) 观察者模式-Observer Pattern[学习难度:★★★☆☆,使用频率:★★★★★] 对象间的联动——观察者模式(一):多人联机对战 ...
- 《Language Implementation Patterns》之 增强解析模式
上一章节讲述了基本的语言解析模式,LL(k)足以应付大多数的任务,但是对一些复杂的语言仍然显得不足,已付出更多的复杂度.和运行时效率为代价,我们可以得到能力更强的Parser. Pattern 5 : ...
- 局部二值模式(Local Binary Patterns)纹理灰度与旋转不变性
Multiresolution Gray Scale and Rotation Invariant Texture Classification with Local Binary Patterns, ...
- .Net Core自实现CLR异步编程模式(Asynchronous programming patterns)
最近在看一个线程框架,对.Net的异步编程模型很感兴趣,所以在这里实现CLR定义的异步编程模型,在CLR里有三种异步模式如下,如果不了解的可以详细看MSDN 文档Asynchronous progra ...
- Javascript编程模式(JavaScript Programming Patterns)Part 2.(高级篇)
模块编程模式的启示(Revealing Module Pattern) 客户端对象(Custom Objects) 懒函数定义(Lazy Function Definition) Christian ...
- Javascript编程模式(JavaScript Programming Patterns)Part 1.(初级篇)
JavaScript 为网站添加状态,这些状态可能是校验或者更复杂的行为像拖拽终止功能或者是异步的请求webserver (aka Ajax). 在过去的那些年里, JavaScript librar ...
- 《Language Implementation Patterns》之 解释器
前面讲述了如何验证语句,这章讲述如何构建一个解释器来执行语句,解释器有两种,高级解释器直接执行语句源码或AST这样的中间结构,低级解释器执行执行字节码(更接近机器指令的形式). 高级解释器比较适合DS ...
随机推荐
- Spring - IoC(7): 延迟实例化
默认情况下,Spring IoC 容器启动后,在初始化过程中,会以单例模式创建并配置所有使用 singleton 定义的 Bean 的实例.通常情况下,提前实例化 Bean 是可取的,因为这样在配置中 ...
- TDS开启log TDS开启SSL
参考: http://www.ibm.com/developerworks/tivoli/library/t-tds-perf/ 1. 编辑ldif文件如下 dn: cn=Audit, cn=Log ...
- 【BZOJ】1579: [Usaco2009 Feb]Revamping Trails 道路升级
[算法]分层图最短路 [题解] 考虑k层一模一样的图,然后每个夹层都在每条边的位置新加从上一层跨越到下一层的边权为0的边,这样至多选择k条边置为0. 然后考虑方便的写法. SPFA 第一次SPFA计算 ...
- 为什么VS没有提供平win64程序编写项
最近在学习C++和MFC编程,突然有个疑问,为什么每次新建项目时,都只有win32 console application,从来没见过win64的选项,于是去网上查了查,下面是我找到的几个答案: 作者 ...
- 说出JAVA中一些常用的类,包,接口,请各举5个~~~
类:1.java.lang.Object2.java.lang.String3.java.lang.System4.java.io.file5.java.io.FileInputStream6.jav ...
- python3 匿名函数,map/reduce/filter等函数结合应用
匿名函数就是不需要显式的指定函数 # 平方函数 def func1(x): return x**2 print(func1) # 平方函数匿名函数写法 func2=lambda x:x**2 prin ...
- 网络知识===cookie 、session、JSESSIONID的区别
cookie .session ? 让我们用几个例子来描述一下cookie和session机制之间的区别与联系.笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微 ...
- 更换介质:请把标有…… DVD 的盘片插入驱动器“/media/cdrom/”再按回车键“ 解决方法
https://blog.csdn.net/no7oor/article/details/12776815
- /usr/bin/env: php: No such file or directory 【xunsearch demo项目体验】【已解决】
出现这个问题的原因是/usr/local/bin 或 /usr/bin 下面没有php可执行文件 解决办法: 建立一条硬链接 ln /path/to/bin/php /usr/local/bin/p ...
- centos6.5 中文输入法图标和提示都不见了【解决】
原因python升级引起的 两步解决: # vi /usr/bin/ibus-setup # vi /usr/libexec/ibus-ui-gtk 把这两个文件中的exec python 修改为 e ...