JMS 队列拆分。企业集成。阿帕奇骆驼
Posted
技术标签:
【中文标题】JMS 队列拆分。企业集成。阿帕奇骆驼【英文标题】:JMS Queue Split. Enterprise Integration. Apache Camel 【发布时间】: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 确实更有意义。 【参考方案1】:1. 你真的需要一个队列来传输到数据库吗?您可以在第一条路由中使用 bean(dbSaver),或者将其抽象为“直接”路由而不是消耗 jms 的路由。这样一来,您就有了两个队列,而不是三个。
2. 第二种方法:如果您可以控制数据库,则可以将第二种类型的消息写入不同的表。然后,一个 sql-consumer 可以轮询记录,并在使用它们时删除它们并将它们传递给 http 服务。但是,该表的行为就像“滚动你自己的 Q”。可能更多的工作回报很少,所以也许第二个队列更好。
3. 最后,我想知道您是否可以重复使用相同的队列。我看到一个选项可以让你写回同一个队列。您可以添加标题并写回某些消息。这可能看起来令人困惑,并且错误可能会导致无限循环。
如果您已经使用 JPA,则可以通过使用 camel-jpa 组件来简化此操作。作为消费者,它读取和删除记录(默认行为)。我认为 SQL/JDBC 组件没有开箱即用的东西。
【讨论】:
感谢您的回复。第一个选项似乎是目前最合适的。我也考虑过第三个选项,但它可能会导致真正令人困惑的繁琐代码,但如果 Camel 提供这种开箱即用的功能,那就太好了。你能帮我解决这个问题吗? 如果你使用 JPA,它会使#3 更容易。我已经编辑了答案, 我会选择#1,它是最明智和可扩展的一个以上是关于JMS 队列拆分。企业集成。阿帕奇骆驼的主要内容,如果未能解决你的问题,请参考以下文章
阿帕奇·德斯德·阿帕奇·德斯德·阿帕奇·德斯德·阿帕奇·德斯德·阿帕奇·阿帕奇·德斯德·阿帕奇·阿帕奇·德斯德·阿帕奇·阿帕奇·德斯德·阿帕奇·阿帕奇·德斯德·阿帕