2010-02-21 69 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