In the last few posts on sagas, we looked at a variety of patterns of modeling long-running business transactions. However, the general problem of message routing doesn’t always require a central point of control, such as is provided with the saga facilities in NServiceBus. Process managers offer a great deal of flexibility in modeling complex business processes and splitting out concerns. They come at a cost though, with the shared state and single, centralized processor.

Back in our sandwich shop example, we had a picture of an interaction starting a process and moving down the line until completion:

Not quite clear in this picture is that if we were to model this process as a saga, we’d have a central point in which all messages must flow to for decisions to be made on the next step. But is there really any decision to be made in the picture above? In a true saga, we have a sequence of steps and a set of compensating actions (in a very simplistic case). Many times, however, there’s no need to worry about compensations in case of failures. Nor does the order in which we do things change much.

Humans have already found that assembly lines are great ways of breaking down a long process into individual steps, and performing those steps one at a time. Henry Ford’s Model T rolled off the assembly line every 3 minutes. If only one centralized worker coordinated all steps, it’s difficult to imagine how this level of throughput could be achieved.

The key differentiator is that there’s nothing really to coordinate – the process of steps is well-defined and known up front, and individual steps shouldn’t need to make decisions about what’s next. Nor is there a need for a central controller to figure out the next step – we already know the steps up front!

In our sandwich model, we need to tweak our picture to represent the reality of what’s going on. Once I place my order, the sequence of steps to fulfill my order are known up front, based on simply examining my order. The only decision to be made is to inspect the order and write the steps down. My order then flows through the system based on the pre-defined steps:

Each step doesn’t change the order, nor do they decide what the next step is (or even care who the next step is). Each step’s job is to simply perform its operation, and once completed, pass the order to the next step.

Not all orders have the same set of steps, but that’s OK. As long as the steps don’t deviate from the plan once started, we don’t need to have any more “smarts” in our steps.

It turns out this pattern is a well-known pattern in the messaging world (which, in turn, borrowed its ideas from the real world): the routing slip pattern.

Routing slips in NServiceBus

Routing slips don’t exist in NServiceBus, but it turns out it’s not too difficult to implement. A routing slip represents the list of steps (and the progress), as well as a place for us to stash any extra information needed further down the line:

We can attach our routing slip to the original message, so that each step can inspect the slip for the next step. We’ll kick off the process when we first send out the message:

Each handler handles the message, but doesn’t really need to do anything to pass it down the line, we can do this at the NServiceBus infrastructure level.

The nice aspect of this model is that it eliminates any centralized control. The message flows straight through the set of queues – leaving out any potential bottleneck our saga implementation would introduce. Additionally, we don’t need to resort to things like pub-sub – since this would still force our steps to be aware of the overall order, hard-coding who is next in the chain. If a customer doesn’t toast their sandwich – it doesn’t go through the oven, but we know this up front! No need to have each step to know both what to do and what the next step is.

I put the message routing implementation up on NuGet and GitHub, you just need to enable it on each endpoint via configuration:

If you need to process a message in a series of steps (known up front), and want to keep individual steps from knowing what’s next (or introduce a central controller), the routing slip pattern could be a good fit.

Saga alternatives – routing slips的更多相关文章

  1. How to implement long running flows, sagas, business processes or similar

    转自:https://blog.bernd-ruecker.com/how-to-implement-long-running-flows-sagas-business-processes-or-si ...

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

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

  3. ASP.NET路由[ASP.NET Routing]

    ASP.NET路由[ASP.NET Routing] ASP.NET路由允许你在使用URL时不必匹配到网站中具体的文件,因为这个URL不必匹配到一个文件,你使用了描述用户行为且更容易被用户理解的URL ...

  4. 解读ASP.NET 5 & MVC6系列(12):基于Lamda表达式的强类型Routing实现

    前面的深入理解Routing章节,我们讲到了在MVC中,除了使用默认的ASP.NET 5的路由注册方式,还可以使用基于Attribute的特性(Route和HttpXXX系列方法)来定义.本章,我们将 ...

  5. 解读ASP.NET 5 & MVC6系列(11):Routing路由

    新版Routing功能介绍 在ASP.NET 5和MVC6中,Routing功能被全部重写了,虽然用法有些类似,但和之前的Routing原理完全不太一样了,该Routing框架不仅可以支持MVC和We ...

  6. scala - multiple overloaded alternatives of method bar define default arguments

    同名同位置默认参数不能overload def bar(i:Int,s:String="a"){} def bar(i:String,s:String="b") ...

  7. [ASP.NET MVC 小牛之路]07 - URL Routing

    我们知道在ASP.NET Web Forms中,一个URL请求往往对应一个aspx页面,一个aspx页面就是一个物理文件,它包含对请求的处理. 而在ASP.NET MVC中,一个URL请求是由对应的一 ...

  8. ASP.NET MVC Routing学习笔记(一)

    Routing在ASP.NET MVC中是非常核心的技术,属于ASP.NET MVC几大核心技术之一,在使用Routing之前,得先引入System.Web.Routing,但其实不用这么麻烦,因为在 ...

  9. Routing 功能概述 - 每天5分钟玩转 OpenStack(98)

    路由服务(Routing)提供跨 subnet 互联互通功能. 例如前面我们搭建了实验环境: cirros-vm1      172.16.100.3        vlan100 cirros-vm ...

随机推荐

  1. 封装常用的Javascript跨浏览器方法

    var EventUntil={ // 跨浏览器的添加事件方法 addHandler:function(element,type,handler){ if(element.addEventListen ...

  2. nginx 设置client header 的大小与400错误

    nginx默认的header长度上限是4k,如果超过了这个值 如果header头信息请求超过了,nginx会直接返回400错误可以通过以下2个参数来调整nginx的header上限 client_he ...

  3. python configparse

    # 参考:https://www.cnblogs.com/lily1989/p/8401005.html # https://blog.csdn.net/willhuo/article/details ...

  4. python面向对象进阶(上)

    一 .isinstance(obj,cls)和issubclass(sub,super) (1)isinstance(obj,cls)检查对象obj是否是类 cls 的对象,返回True和Flase ...

  5. Linux调试介绍

    1. 介绍 本文介绍了调试的一些常用函数和工具 2. 函数 用户态函数: backtrace()/backtrace_symbols() 内核态函数: dump_stack() 3. 工具 工具: g ...

  6. git 提示 Please move or remove them before you can merge 解决办法

    解决Git冲突造成的Please move or remove them before you can merge git clean -d -fx其中x -----删除忽略文件已经对git来说不识别 ...

  7. python访问网站

    #!/usr/bin/env python # encoding: utf-8 from functools import wraps import requests from lxml import ...

  8. 【 sysbench 性能基准测试 】

    度娘解释:sysbench是一款开源的多线程性能测试工具,可以执行CPU/内存/线程/IO/数据库等方面的性能测试. 目前支持的数据库支持:MySQL,pgsql,oracle 这3种数据库. 安装s ...

  9. ECharts问题--柱状图和折线图中xAxis.data为空时报错问题解决

    1. 我们在日常的开发中使用Echarts时,不像在学习的过程中是自己在option中的配置项填写图表需要的参数,而是通过ajax请求后台,获取数据后,使用javascript来动态的修改数据,但是有 ...

  10. linux awk学习笔记

    awk学习笔记 awk语法格式 awk '{pattern + action}' {filenames} awk作用 awk的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后 ...