2016-08-10 52 views
5

我有第三方应用程序将一些消息放入JMS队列。 另外我有一个应用程序从这个队列中读取消息。根据消息的类型,我将此消息保存到数据库或发送给第三方服务。此外,我们不应该超过每秒固定呼叫限制,不要超载第三方。JMS队列拆分。企业集成。 Apache Camel

目前,我对这个用例有两种解决方案。

第一个问题是要求第三方发送一些自定义标题,以便JMS使用者能够使用JMS选择器过滤消息。因此,在这种情况下,我们可以创建两个消费者,第一个消费者可以读取消息并将其保存到数据库中,第二个消费者将使用一些调节/轮询机制在特定负载下向第三方发送消息。 但是这种方法对我不起作用,因为第三方需要很长的时间来添加这些自定义标题。像这样在骆驼:

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中会有大量消息,我们可能会很容易陷入内存问题。

任何人都可以提出这个用例的建筑设计吗?以骆驼路线的风格来看它真是太棒了。

+0

有两个额外的队列并不是什么大不了的事情,JMS代理可以处理数千个队列。也就是说,如果你不想对插入物进行批量处理,Darius的选项#1会更有意义。 –

回答

2

1.您是否真的需要一个队列来流向数据库?您可以在第一条路径中使用bean(dbSaver),或者将其抽象为“直接”路由而不是使用jms消耗的路由。这样,你有两个队列而不是三个队列。

2.第二种方法:如果您可以控制数据库,则可以将第二种类型的消息写入不同的表。然后,一个sql-consumer可以轮询记录,并在它们消耗它们并将它们传递给http服务时删除它们。然而,桌子的表现就像是“自己动手”。可能更多的工作是回报很少,所以也许第二个队列更好。

3.最后,我想知道是否可以重复使用相同的队列。我看到一个选项可以让你回写同一个队列。您可以添加标题并回写特定消息。这看起来很混乱,而且一个bug可能会造成一个无限循环。

如果您已经使用JPA,那么可以通过使用camel-jpa组件来简化操作。作为消费者,它执行读取和删除记录(默认行为)。我不认为SQL/JDBC组件有什么像现成的那样。

+0

感谢您的回复。第一种选择似乎是现在最适合的。我也考虑过第三种选择,但它可能会导致令人困惑的繁琐代码,但在Camel提供这种功能的情况下,这很棒。可能你可以帮助我吗? – StasKolodyuk

+0

如果您使用JPA,它会让#3更容易。我已经编辑了答案, –

+0

我会去#1,这是最明智和可扩展的答案 –