2010-02-21 70 views
3

我有一些客戶端既是消費者,又是訂閱ActiveMQ消息代理的單個主題的客戶端。所有的客戶端共享相同的代碼,實際上他們使用正好是相同的企業應用程序,包括:(1)產生消息的EJB,(2)消費該消息的MDB。如何讓我的MDB忽略來自其自身的消息?

問題是,如果我有客戶端A,B和C,並且如果A發出消息,則A,B,C都將接收到消息。我不希望A收到自己的消息。

因此,我使用了各種解決方案,最好的解決方案是在傳出消息上設置字符串屬性,例如, source = myVeryOwnID。然後在MDB中,我設置了一個消息選擇器,如來源<>'myVeryOwnID'

不幸的是,這是一個糟糕的解決方案,因爲我必須在源代碼中設置此ID(在我的情況下,在註釋中)。這意味着在部署新客戶端時,我不能簡單地將.EAR文件給予某人,而必須使用唯一的「源」屬性專門重新編譯。

理想情況下,我想使用MAC地址作爲ID,或者Glassfish(我正在使用GFv3)內的ID設置。

任何解決方案或想法將不勝感激!

+0

如果您使用glassfish,爲什麼'activemq'標籤?您是否使用Glassfish JMS或ActiveMQ? – skaffman 2010-02-21 11:26:31

+0

但是,您要部署相同的EAR三次還是一次? – ewernli 2010-02-21 12:48:02

+0

skaffman:我很抱歉沒有說清楚。我確實使用ActiveMQ,而不是與Glassfish捆綁在一起的OpenMQ。 ewernli:我希望三次部署相同的EAR。但是現在,我必須重新構建EAR(以確保源標識符不同)三次,然後進行部署。 – 2010-02-22 12:12:22

回答

2

在消息中使用「源」消息屬性和消息選擇器是恕我直言的路要走。現在,如果您不想在MDB中對其進行硬編碼(在註釋中),請使用deployment descriptor並在打包時設置消息選擇器。

+0

我也考慮過使用部署描述符,但它給我帶來了同樣的問題。 我將不得不幾次構建相同的.EAR,即每個客戶端一個。 如何使用Glassfish中的連接工廠(使用ActiveMQ資源適配器),然後將「clientId」設置爲屬性。我需要一個clientId用於我的持久訂閱,並且將它用於我的「源」屬性也是非常好的。 但是,我一直在試圖做到這一點,我不知道如何從我的工廠獲得clientId。 – 2010-02-22 12:35:27

+1

@ T.K。問題只是從編譯時間轉移到打包部署時間(這可能會更方便一些,但不是很多),但這是事情本來應該如何工作的:「應用程序組裝者」必須設置這些類型的東西時打包和部署由「應用程序組件提供程序」(http://java.sun.com/javaee/5/docs/tutorial/doc/bnaca.html#bnach)提供的組件。 – 2010-02-22 13:18:36

0

簡單的舊System.GetProperty()和-D選項呢?您可以設置唯一的應用程序ID作爲系統屬性:

-Dmyapp.id=A

例如在Tomcat中,你可以通過JAVA_OPTS變量傳遞系統屬性:

export JAVA_OPTS='-Dmyapp.id=A' 

然後你就可以在應用程序讀取它:

String appId = System.getProperty("myapp.id") 

所有你必須做的是爲你的每個應用服務器設置系統變量。

+0

我仍然沒有看到它會如何工作。 – ewernli 2010-02-28 12:37:27

+0

這個傢伙需要每個正在運行的應用程序的唯一ID。他不想將此ID硬編碼到源代碼中。使用系統屬性爲每個正在運行的應用程序設置(您使用-D選項傳遞id)可解決此類問題。 減號是因爲...? – 2010-02-28 13:50:13

+0

亨利克你是對的。我至少贊成你。 – 2010-03-01 11:51:09

1

ActiveMQ包含一個方法參數來處理這種情況。 ActiveMQSession.createConsumer()方法和ActiveMQSession. createDurableSubscriber()方法都提供了一個接受名爲noLocal的參數的變體。將noLocal參數設置爲true以避免接收在同一連接上本地發佈的消息。

布魯斯

+0

非常好的一點。謝謝。 – 2010-03-04 12:51:45