按定义的顺序处理一组相关的消息,不需阻止对其他消息组的处理。
上下文和问题
应用程序通常需要按照消息到达的顺序处理消息序列,同时仍可以横向扩展以处理增加的负载。 在分布式体系结构中,按顺序处理这些消息并不是很简单,因为辅助角色可以独立缩放,并且通常使用竞争性使用者模式单独提取消息。
例如,订单跟踪系统接收包含订单的分类帐和对这些订单的相关操作。 这些操作可能是创建订单、向订单中添加事务、修改过去的交易或删除订单。 在此系统中,必须按照先进先出 (FIFO) 方式执行操作,但只能在订单级别执行操作。 不过,初始队列接收多个订单的包含多个订单的交易,这可能是交错的。
解决方案
将相关的消息推送到队列系统内的类别中,并让队列侦听器锁定并仅从一个类别(一次一个消息)中请求。
一般顺序保护模式如下所示:
![](https://img.haomeiwen.com/i1779921/e15ba12fa83a17dc.png)
在队列中,不同类别的消息可能交错,如下图所示:
![](https://img.haomeiwen.com/i1779921/bb3fc8d79aa82f7c.png)
问题和注意事项
在决定如何实现此模式时,请考虑以下几点:
- 类别/缩放单位。 你可以向外扩展传入消息的哪个属性? 在订单跟踪方案中,此属性为订单 ID。
- 吞吐量。 目标消息吞吐量是多少? 如果它很高,则可能需要重新考虑 FIFO 要求。 例如,你是否可以强制执行开始/结束消息、按时间排序,并发送一个批处理以便进行处理?
- 服务功能。 您选择的消息总线是否允许对队列或队列类别中的消息进行一次性处理?
- 可进化性. 如何向系统添加新的消息类别? 例如,假定上面所述的会计系统是特定的客户。 如果你需要加入新客户,你是否可以拥有一组按客户 ID 分配工作的分类帐处理器?
- 由于发送消息时出现可变网络延迟,因此使用者可能会因为消息不按顺序接收消息。 请考虑使用序列号验证排序。 你还可以在事务的最后一条消息中包含一个特殊的 "序列结尾" 标志。 流处理技术(例如 Spark 或 Azure 流分析)可以在某个时间范围内按顺序处理消息。
何时使用此模式
在以下情况下使用此模式:
- 您有按顺序到达并按顺序处理的消息。
- 传入的消息是或可 "分类的",这种方式使类别成为系统的规模单位。
此模式可能不适用于以下情况:
- 极高的吞吐量方案 (数百万条消息/分钟或秒) ,因为 FIFO 要求会限制系统可以执行的缩放。
网友评论