2016-08-10 55 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,這是最明智和可擴展的答案 –