2009-10-17 18 views
0

我有一個要求,即客戶端發送的單個JMS消息必須可靠(準確一次)傳送到兩個系統。未啓用HA這2個系統,所以我想出了最好的建議是:如何將JMS消息「複製」到2個目的地?

  1. 創建單個隊列,其中客戶端職位,以

  2. 設立了兩個「中間」隊列

  3. 使用自定義的「DuplicatorMDB」將讀取來自客戶端隊列的消息並將其發佈到同一事務中的兩個隊列中。

 
client->JMSDQ->DuplicatorMDB->Q1->MDB->System1 
          \->Q2->MDB->System2 

是否有這樣的任何現有的功能?如果一個或兩個後端系統停機,平衡系統以保持系統穩定的正確方法是什麼?

應用服務器的WebLogic 10

我不能用這個主題,因爲集羣中的主題將造成太大的消息重複。如果我們有2個實例,然後用主題,它會是這樣的:

 
client->Topic-->[email protected]>System1 
      | \->[email protected]>System2 
      \---->[email protected]>System1 
      \--->[email protected]>System2 

因此,每一個消息都需要進行兩次交付給系統1和兩次系統2,如果有會在一個集羣8個服務器,每個消息將交付8次。這是我真正想避免的...

最後我有一些時間來測試它,這裏是我觀察到的: 集羣中的2個節點。 2個JMS服務器:node1上的jms1,node2上的jms2。 分佈式主題dt。具有持久訂閱的MDB和jms-client-id = durableSubscriber。啓動系統:0消息,mdb @ node1啓動,mdb @ node2嘗試定期連接,但不能因爲「客戶端ID,durableSubscriber,正在使用」。如預期。

發送100條消息: jms1 @ dt消息當前= 0,消息總數= 100,消費者當前= 1 我可以看到node1處理了100條消息。
jms2 @ dt消息當前= 100,消息總數= 100,消費者當前= 1 即在主題中「重複」消息未決。

在另外100條消息中發送,100個在node1上處理,200在node2上掛起。

重新啓動node1,mdb @ node2重新連接到dt並開始處理「掛起」消息。在節點2上處理了200條消息。

在node1啓動後,mdb @ node1無法連接到dt,而mdb @ node2已連接。

jms1 @ dt的消息電流= 0,消息總共= 0,消費者電流= 0
jms2 @ dt的消息電流= 0,消息總數= 200,消費者電流= 1

發送在100多個消息,我看到所有100條消息都在節點2上處理並在節點1上丟棄。

jms1 @ dt的消息電流= 0,消息總數= 100,消費者電流= 0
jms2 @ dt的消息電流= 0,消息總數= 300,消費者電流= 1

現在我重新啓動節點2,MDB @ node1重新連接到dt。重新引導後,mdb @ node2重新連接到dt,mdb @ node1從dt斷開連接。

jms1 @ dt的消息電流= 0,消息總數= 100,消費者電流= 1
jms2 @ dt的消息電流= 0,消息總共= 0,消費者電流= 1

我在100個消息中發送,所有都在節點2處理並存儲在主題在node1:

jms1 @ dt的消息電流= 100,消息總數= 200,消費者電流= 1
jms2 @ dt的消息電流= 0,消息總共= 0,消費者電流= 1

然後我關閉否de2,並且我看到在mdb @ node1重新連接到主題後,在node1上處理了100個「待處理消息」。

所以結果是: 我發送了400條消息,其中700條由MDB處理,其中300條是重複的。

它看起來像MDB重新連接工作良好,但如果託管「活動」MDB的節點出現故障,則消息可能會重複。

這可能是weblogic JMS實現的缺陷或功能。

+1

我錯過了什麼嗎?爲什麼不使用主題? – SingleShot 2009-10-17 07:12:03

+0

對持久訂閱的任何反饋? – 2009-10-20 09:43:07

回答

1

我沒有使用過Weblogic,但大多數JMS解決方案都有隊列和主題的概念。你想要一個JMS主題。訂閱者註冊並且該主題確保消息被傳遞給每個訂閱者一次。

Configuration details

更新:如果您遇到集羣環境中的問題,我會確保一切配置正確(這是JMS Topic Clustering的指南)。 Weblogic在集羣時會非常糟糕地失敗,這聽起來很奇怪。如果這不起作用,您可以查看第三方消息隊列,如支持JMS的RabbitMQ,並且絕對不會有此問題。

+0

羣集中的主題存在問題,將會創建太多的郵件副本 - 請參閱郵件更新... – 2009-10-17 07:24:24

0

這是一種ESB實現應該禁止的行爲。就處理開銷而言,沒有太大的區別,但將「管道」和應用程序代碼之間的關注點分開是有用的。

碰巧,WebSphere JMS實現支持安裝解決這些需求的調解。我不知道WebLogic是否有類似的東西,或者他們的ESB產品是否適合您,但我會建議您研究這些功能。您目前有一個簡單的要求,並且您的代碼肯定是足夠的,但是很容易想象如何有一些小的附加要求(我們可以在將該字段從美元轉換爲磅之前轉發到目標,我們是否可以不發送消息這個內容到那個目的地......)和lo!你發現自己寫了你自己的ESB。

+0

無需使用ESB IMO,這是主題的用途。 – 2009-10-18 11:10:02

+0

我從最初的聲明中看到,無法在提問者的案例中使用主題。我認爲你已經表示實際上可以使用主題,在這種情況下,我同意這會更好。再次,一般原則是,如果可能的話,儘量避免自己實施管道。 – djna 2009-10-18 11:57:22

0

[...]因此每條消息將被傳遞兩次到System1和兩次到System2,並且如果羣集中將有8個服務器,每個消息將被傳遞8次。這是我真正想避免的...

這對非持久訂閱是正確的,但不是持久的。對於持久性,所有MDB共享相同的連接ID和訂閱ID(默認情況下基於MDB名稱),因此一次只能有一個MDB連接和接收消息。第一個要嘗試的MDB將成功連接,其他人將檢測到衝突並失敗,但要繼續重試。因此,使用持久主題訂閱應該能夠做到這一點。

+0

我想你的意思是持久訂閱,因爲這是接收者的財產,而不是主題。 如果MDB具有持久預訂(並且必須指定ClientID才能執行此操作),那麼它只能部署在羣集中的一個節點上。在WLS部署到第二個節點失敗,因爲已經有一個客戶端具有相同的客戶端ID。 – 2009-10-18 06:50:33

+0

來自WLS10文檔:「訂閱ID在其主題上必須是唯一的,因此具有持久主題訂閱的MDB無法在羣集中的多個服務器實例上運行。」 http://download.oracle.com/docs/cd/E12839_01/web.1111/e13719/message_beans.htm#i1161176 – 2009-10-18 07:36:33

+0

是的,這就是我的意思,我不夠清楚。關於文件,我不確定你想表達什麼。爲什麼不粘貼整個段落:「訂閱ID在其主題上必須是唯一的,因此具有持久主題訂閱的MDB無法在羣集中的多個服務器實例上運行。在MDB的第一個實例在服務器上啓動後實例在集羣中,EJB的另一個實例可以在另一個集羣服務器上成功部署,但是當MDB啓動時,檢測到衝突並且該MDB實例無法完全連接到JMS。 – 2009-10-18 09:14:44