因此,在非独占队列中,我们已对消息进行了排序(例如,ID 123更新事件将在ID 123创建事件之后)。当我们只有一个使用者时,一切都很好,但是需要水平可伸缩性。通过生成另一个使用者,我了解到代理将在其中进行循环操作,因此可以在其创建事件之前处理更新事件。
是否有解决此问题的现有模式?我知道有些经纪人,例如kafka和activemq都支持它,通过在发布过程中指定ID,它将确保所有具有该ID的消息仅在一个使用者上排列。因此,尊重事件的顺序。
((我的博客摘录中尚未发布的内容)
[有时要求发布的事件或消息数据包含特定的属性-例如,客户ID,订单ID,产品ID等-始终按其产生时的原始订单进行处理。此要求意味着所有相关消息均传递给同一消费者(或可能是一组消费者)。也就是说,消息包含key,这样具有相同密钥的后续消息总是传递给相同的使用者并按顺序进行处理。这样可以确保始终按顺序处理有关特定属性的更改或更新。
术语“ 消费者组”由日志传送应用程序Apache Kafka推广。在卡夫卡,消费者群体是形成“逻辑消费者”以从单个主题中读取的消费者群体。 Kafka使用者组中的使用者连接到Kafka主题内的一个或多个分区,并从分区文件中读取顺序日志记录。当记录(“消息”)附加到Kafka主题中的分区时,该分区由发布者定义的键属性选择。
这提供了一种“ 粘性负载平衡”的形式,使得具有相同键的记录最终位于同一分区中,因此由同一使用者处理。
[使用分层主题结构和Solace的高级主题过滤器功能,可以在Solace中实现相同(更好)的功能。
定义主题层次结构或分类法时,将主题层次结构的一级指定为分区键。例如。对于订单输入系统,您的主题结构可以是:
estore/order/[ORDER_ID_PARTITION_KEY]/more/specific/rest/of/topic
密钥通常是已发布数据的重要属性的哈希,如开头所述。在我们的示例中,键控属性将是订单ID,即大整数。为了简单起见,我们假定分区键为:模ID的阶数8:0..7之间的整数,给出8个可能的值,最多8个可能的分区。
要在Solace中配置粘性负载平衡,请至少配置与“消费者组”中的消费者数量一样多的队列...让我们说两个!但是,为了便于将来扩展,请考虑配置更多的队列并让使用者绑定到多个队列:
请注意,在订阅的结尾使用了Solace多层通配符>
。
在此eStore示例中,如果增强了客户网关/ API以允许使用不同类型的订单事件(例如new
,amend
,cancel
),则希望将与同一订单ID相关的事件转到相同的后端处理器。这样可以确保一个处理器不会收到new
订单,并且将cancel
路由到另一个处理器。每当发布者生成“订单”类型的事件时,该主题的第3级将通过使用订单ID的模8(或其他形式)将消息键入特定分区。]
可能有非常大量的分区,使用主题定义分区的方法基本上没有改变架构模式(因为主题和订阅在Solace中是“便宜”的)。通过能够在新数量的队列中重新平衡密钥订阅,从而能够将更多消费者添加到消费者组中,从而提供了未来的灵活性。只需从一个相当大的哈希键空间开始,或者以模数开始...这样,发布者就不必担心更改其分区键算法!
请注意,这种方法还允许您使用两个不同级别的主题层次结构来键入两个不同的属性。一组队列可以在一个级别上查看,另一组队列可以在不同级别上进行分片。
希望有帮助!
有序消息传递和水平缩放的想法本质上是相互矛盾的。为了获得顺序,必须在使用下一条消息之前完全消耗和确认每个消息。这导致serial消息处理(即没有并发)。但是,水平可伸缩性的想法是通过添加可以同时处理消息的使用者来增加消息吞吐量。如您所见,如果要进行有序的消息处理,则不能同时使用消息,这会破坏水平扩展的全部目的。
ActiveMQ(通常是JMS)支持您在问题中提到的“消息分组”的思想(同一组中的所有消息共享相同的分组属性ID值)。经纪人选择单个消费者以接收特定组中的所有消息,以便按顺序(即按顺序)处理消息。由于仅订购特定的消息组,因此可以允许同时使用多个组的消息。但是,队列的基本先进先出语义仍然成立,因此,如果每个组或少数组中有很多消息,则总体消费者并发性仍然很低,并且肯定会低于如果您根本不需要订购。尽管我在这里专门讲ActiveMQ,但是对于任何消息代理来说,都没有真正的解决方法,因此同样适用于Solace(假设它甚至首先支持消息分组)。