并发消费者,但确保订单

时间:2012-07-19 19:33:34

标签: java jms eai enterprise-integration

我有一个以非常高的速率(> 100,000 /秒)填充的JMS队列。

可能会发生每秒都有多个与同一实体有关的消息。 (对实体的多次更新,每次更新都是不同的消息。)

另一方面,我有一个消费者处理此消息并将其发送到其他应用程序。

现在,整个设置正在放缓,因为消费者无法应对传入消息的速度。

由于消费者处理消息的速率存在SLA,我一直在想让多个消费者并行行动以加快这一过程。

所以,我想要做的是

  • 多个消费者在队列中独立行动。
  • 每个消费者都可以随意抓取任何消息。
  • 抓取消息后,请确保其是最新版本的实体。为此,我可以检查处理此实体的应用程序。
  • 如果不是最新版本,请将版本提升并重试。

我一直在查找集成模式,JMS文档到目前为止没有成功。

我希望能够以更优雅的方式解决这个问题以及Java世界中任何已知的API模式。

3 个答案:

答案 0 :(得分:2)

ActiveMQ使用a concept called "Message Groups"解决了这个问题。虽然它不是JMS标准的一部分,several JMS-related products work similarly。基本思路是将每条消息分配给一个“组”,该组指示相关且必须按顺序处理的消息。然后进行设置,以便每个组仅交付给一个消费者。因此,您可以在组之间实现负载平衡,但保证组内的按顺序交付。

答案 1 :(得分:0)

大多数EIP框架和ESB都有可定制的重新排序器。如果实体的数量不是太大,您可以在每个实体上有一个队列,并在开头重新排序。

答案 2 :(得分:0)

对于那些对解决这个问题感兴趣的人:

由于问题是关于JMS,我们可以看看Apache Camel website中的一个例子。

这种方法与CBRSelective Consumer等其他模式不同,因为消费者不知道它应该处理什么消息。 让我把它放在一个现实世界的例子中:

我们有一个订单管理系统(OMS),它发送订单以供ERP处理。然后,订单将执行6个步骤,每个步骤都会在Order_queue上发布一个事件,通知新订单的状态。这里没什么特别的。 OMS使用来自该队列的事件,但是必须以与发布它们相同的顺序处理每个Order的事件。每分钟发布的消息速率远远大于消费者的吞吐量,因此延迟会随着时间的推移而增加。

解决方案要求:

  • 并行消费,包括尽可能多的消费者以保持合理数量的队列大小。
  • 保证每个订单的事件在同一发布订单中处理。

实施:

在OMS方面 负责将订单发送到ERP的OMS流程确定将处理特定订单的所有事件的消费者,并将订户的名称与订单一起发送。 这个过程如何知道收件人应该是什么?好吧,你可以使用不同的方法,但我们使用了一个非常简单的方法:Round Robin

关于ERP 由于它保留了每个订单的收件人名称,因此只需将邮件设置为传递给所需的收件人。

在OMS消费者上 我们已经部署了4个实例,每个实例使用不同的收件人名称并同时处理消息。

可以说我们创造了另一个瓶颈:数据库。但事实并非如此,因为订单行上没有并发。

一个缺点是将订单发送到ERP的OMS流程必须了解有多少收件人正在工作。