【发布时间】:2016-12-17 02:26:56
【问题描述】:
我有一个将一些消息放入 JMS 队列的第三方应用程序。 我也有一个应用程序从这个队列中读取消息。根据消息的类型,我将此消息保存到 DB 或将其发送到第三方服务。此外,我们不应该超过一些固定的每秒调用限制,以免第三方超载。
目前,针对这个用例,我想到了两种解决方案。
第一个是要求第三方发送一些自定义标头,以便 JMS 消费者能够使用 JMS 选择器过滤消息。因此,在这种情况下,我们将能够创建两个消费者,第一个将能够读取消息并将它们保存到数据库,第二个将使用一些节流/轮询机制在特定负载下向第三方发送消息. 但是这种方法对我不起作用,因为第三方添加这些自定义标题需要很长时间。在 Camel 中是这样的:
from("jms:queue?selector=firstSelector")
.bean(dbSaver);
from("jms:queue?selector=secondSelector")
.throttle(10)
.bean(httpClient);
第二个是创建另外两个 JMS 队列和一个将在这些队列之间拆分消息的处理器。然后采用与第一个解决方案相同的逻辑。但是,这意味着应该添加 2 个额外的 JMS 队列。在骆驼中:
from("jms:parentQueue")
.choice()
.when(body().contains(...))
.to("jms:fistChildQueue")
.otherwise()
.to("jms:secondChildQueue")
.end()
from("jms:fistChildQueue")
.bean(dbSaver);
from("jms:secondChildQueue")
.throttle(10)
.bean(httpClient);
另外,我一直在考虑使用两个内存队列而不是 JMS 队列。但是,在这种情况下,如果 JMS Queue 中有大量消息,我们很容易陷入内存问题。
谁能为这个用例推荐一个架构设计?很高兴看到它以骆驼路线风格出现。
【问题讨论】:
-
拥有两个额外的队列没什么大不了的,JMS 代理可以处理数千个队列。话虽如此,如果您不想进行任何批处理插入,Darius 的选项 #1 确实更有意义。
标签: java apache-camel jms throttling enterprise-integration