3

所以在非排他队列上,我们对消息进行了排序(例如,id 123 更新事件将在 id 123 创建事件之后)。当我们只有一个消费者时一切都好,但需要水平可伸缩性。通过产生另一个消费者,我知道代理将在其中进行循环,因此更新事件可以在其创建事件之前处理。

关于如何解决这个问题,是否有任何现有的安慰模式?我知道像 kafka 和 activemq 这样的一些代理支持它,通过在发布期间指定 id 将确保具有该 id 的所有消息将仅在一个消费者上排队;因此,尊重事件的顺序。

4

3 回答 3

2

有序消息传递和水平扩展的想法本质上是相互矛盾的。为了实现顺序,必须在消费下一条消息之前完全消费并确认每条消息。这导致串行消息处理(即没有并发)。但是,水平可扩展性的想法是通过添加可以同时处理消息的消费者来增加消息吞吐量。如您所见,如果您想要有序的消息处理,则不能同时使用消息,这违背了水平扩展的整个目的。

ActiveMQ(以及一般的 JMS)支持您在问题中提到的“消息分组”的想法(同一组中的所有消息共享相同的分组属性 ID 值)。代理选择单个消费者来接收特定组中的所有消息,以便按顺序(即按顺序)处理消息。由于仅对特定的消息组进行排序,因此可以同时使用来自多个组的消息。但是,队列的基本先进先出语义仍然成立,因此如果您在每个组或少数组中有大量消息,您的整体消费者并发性仍然会相当低,而且肯定很多低于您根本不需要订单的情况。尽管我在这里专门谈论 ActiveMQ,但对于任何消息代理都没有真正的解决方法,因此同样适用于 Solace(假设它甚至首先支持消息分组)。

于 2020-01-29T18:53:32.287 回答
2

(摘自我尚未发布的博客)

有时要求包含特定属性(例如客户 ID、订单 ID、产品 ID 等)的已发布事件或消息数据始终按照其生产时的原始订单进行处理。此要求意味着所有相关消息交付给相同的消费者(或可能的消费者组)。也就是说,消息包含一个密钥,因此具有相同密钥的后续消息始终传递给同一消费者并按顺序处理。这可确保始终按顺序处理有关特定属性的更改或更新。

消费者组”一词由 Apache Kafka(一种日志传送应用程序)推广。在 Kafka 中,消费者组是构成“逻辑消费者”以读取单个主题的消费者组。Kafka 消费者组中的消费者连接到 Kafka 主题内的一个或多个分区,并从分区文件中读取顺序日志记录。当记录(“消息”)附加到 Kafka 主题中的分区时,分区由发布者定义的键属性选择。

这提供了一种“粘性负载平衡”形式,使得具有相同键的记录最终位于同一分区中,因此由同一消费者处理。

使用分层主题结构和 Solace 的高级主题过滤功能,可以在 Solace 中实现相同(和更好)的功能。

使用 Solace 主题进行分区

定义主题层次结构或分类时,将主题层次结构的一级指定为分区键。例如,对于订单输入系统,您的主题结构可以是:

estore/order/[ORDER_ID_PARTITION_KEY]/more/specific/rest/of/topic

密钥通常是已发布数据的重要属性的散列,如前一段所述。在我们的示例中,键控属性是订单 ID,一个大整数。为简单起见,让我们假设分区键为: 订单 ID 模 8:0..7 之间的整数,给出 8 个可能的值,最多 8 个可能的分区。

要在 Solace 中配置粘性负载平衡,请至少配置与“消费者组”中消费者数量一样多的队列……比如说两个!但是,为了便于将来扩展,请考虑配置更多队列并让消费者绑定到多个队列:

enter image description here

>请注意在订阅末尾使用 Solace 多级通配符。

在这个 eStore 示例中,如果客户网关/API 被增强以允许不同类型的订单事件(例如newamendcancel),则与相同订单 ID 相关的事件将需要发送到相同的后端处理器。这将确保new订单不会被一个处理器接收,并且会cancel被路由到另一个处理器。每当发布者生成“订单”类型的事件时,主题的第 3 级用于通过取订单 ID 的模 8(或其他值)将消息键入特定分区。

使用这种方法可以拥有非常多的分区,而架构模式基本上没有变化,使用主题来定义分区(因为主题和订阅在 Solace 中是“便宜的”)。这通过在新的队列数量上重新平衡密钥订阅,能够将更多的消费者添加到消费者组中,从而实现未来的灵活性。只需从相当大的散列键空间或模数开始...这样发布者就不必担心更改其分区键算法!

请注意,此方法还允许您使用主题层次结构的两个不同级别来键入两个不同的属性。一组队列可以查看一个级别,另一组队列可以在不同级别进行分片。

希望有帮助!

于 2020-01-31T04:24:24.090 回答
1

本质上,您正在寻找的是粘性负载平衡:具有特定键的消息分配给同一个使用者,而具有不同键的整体消息可以在不同的使用者之间进行负载平衡。看看我的同事 Mat Hobbis 的这篇博客,它描述了如何使用 Solace PubSub+ 完成此操作: https ://solace.com/blog/sticky-load-balancing-in-solace-pubsub-event-broker/

于 2020-01-30T09:35:17.717 回答