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学习--切面优先级及重用切点表达式
指定切面的优先级: 在同一个链接点上应用不止一个切面时 , 除非明确指定 , 否则它们的优先级是不确定的. 切面的优先级可以通过实现 Ordered 接口或利用 @Order 注解指定. 实现 Ord ...
- MDIO/MDC(SMI)接口-leonwang202
ChinaUnix博客 http://blog.chinaunix.net/uid-24148050-id-132863.html
- 【spoj8222-Substrings】sam求子串出现次数
http://acm.hust.edu.cn/vjudge/problem/28005 题意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.求F(1)..F(Length( ...
- 【洛谷 UVA11417】 GCD(欧拉函数)
我们枚举所有gcd \(k\),求所有\(gcd=k\)的数对,记作\(f(k)\),那么\(ans=\sum_{i=1}^{n}(f(i)-1)*i\).为什么减1呢,观察题目,发现\(j=i+1\ ...
- JS组件入门
用React感觉component老好用了. 那如何用原生JS来模拟实现React中的component方法呢:http://huziketang.com/blog/posts/detail?post ...
- C++11 自动释放锁(转)
原文转自 https://blog.csdn.net/lmb1612977696/article/details/77712170 c++11加入了很多新的特性,值得我们去探索. 先看一个例子:普通的 ...
- LeetCode 10 Regular Expression Match
'.' Matches any single character.'*' Matches zero or more of the preceding element. The matching sho ...
- [Leetcode Week3]Course Schedule
Course Schedule题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/course-schedule/description/ Descript ...
- linux中的阻塞机制及等待队列【转】
转自:http://www.cnblogs.com/gdk-0078/p/5172941.html 阻塞与非阻塞是设备访问的两种方式.驱动程序需要提供阻塞(等待队列,中断)和非阻塞方式(轮询,异步通知 ...
- python之八大排序方法
一.插入排序 #-*- coding:utf-8 -*- ''' 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时 ...