如何让我的 MDB 忽略来自自身的消息?

Posted

技术标签:

【中文标题】如何让我的 MDB 忽略来自自身的消息?【英文标题】:How do I get my MDB to ignore messages coming from itself? 【发布时间】:2011-01-19 07:49:05 【问题描述】:

我有几个客户端,它们既是 ActiveMQ 消息代理上单个主题的消费者又是订阅者。所有客户端共享相同的代码,实际上它们完全使用相同的企业应用程序,包括:(1) 一个产生消息的 EJB,和 (2) 一个使用该消息的 MDB。

问题基本上是,如果我有客户端A,B和C,如果A发出消息,那么A,B,C都会收到消息。我不希望 A 收到自己的消息。

所以我尝试了各种解决方案,我想出的最好的一个是在传出消息上设置一个字符串属性,例如source=myVeryOwnID。然后在 MDB 中,我设置了一个消息选择器,例如 source 'myVeryOwnID'

不幸的是,这是一个糟糕的解决方案,因为我必须在源代码中设置这个 ID(在我的例子中,在注释中)。这意味着在部署新客户端时,我不能简单地将 .EAR 文件提供给某人,而是必须使用唯一的“源”属性专门重新编译。

理想情况下,我想使用 MAC 地址作为 ID,或者可能是 Glassfish 中设置的 ID(我使用的是 GFv3)。

任何解决方案或想法都将受到高度赞赏!

【问题讨论】:

如果您使用的是 glassfish,为什么要使用 activemq 标签?您使用的是 Glassfish JMS 还是 ActiveMQ? 但是您是部署同一个 EAR 三次还是只部署一次? skaffman:我很抱歉没有说清楚。我确实使用的是 ActiveMQ,而不是与 Glassfish 捆绑的 OpenMQ。 ewernli:我希望部署相同的 EAR 三次。但是,就像现在一样,我将不得不重新构建 EAR(以确保源标识符不同)三次,然后部署。 【参考方案1】:

在消息中使用“源”消息属性和消息选择器是恕我直言的方法。现在,如果您不想在 MDB 中(在注释中)对其进行硬编码,请使用 deployment descriptor 并在打包时设置消息选择器。

【讨论】:

我也考虑过使用部署描述符,但它给我留下了同样的问题。我将不得不多次构建相同的 .EAR,即每个客户一个。如何在 Glassfish 中使用连接工厂(使用 ActiveMQ 资源适配器),然后将“clientId”设置为属性。我需要一个 clientId 用于我的持久订阅,并且将它用于我的“源”属性也很棒。但是,我一直在尝试这样做,但我不确定如何从我的工厂获取 clientId。 @T.K.问题只是从编译时间转移到打包部署时间(这可能更方便一点,但不多),但这就是事情最初应该如何工作:“应用程序汇编程序”必须设置这些东西时由“Application Component Provider”(java.sun.com/javaee/5/docs/tutorial/doc/bnaca.html#bnach)提供的打包和部署组件。【参考方案2】:

ActiveMQ 包含一个方法参数来解决这种情况。 ActiveMQSession.createConsumer() 方法和ActiveMQSession. createDurableSubscriber() 方法都提供了一个变量,它接受名为noLocal 的参数。将 noLocal 参数设置为 true 以避免接收在同一连接上本地发布的消息。

布鲁斯

【讨论】:

【参考方案3】:

那普通的旧 System.GetProperty() 和 -D 选项呢?您可以将唯一的应用程序 ID 设置为系统属性:

-Dmyapp.id=A

例如在 Tomcat 中,您可以通过 JAVA_OPTS 变量传递系统属性:

export JAVA_OPTS='-Dmyapp.id=A'

然后你可以在应用程序中读取它:

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

您只需为每个应用程序服务器设置系统变量。

【讨论】:

这个家伙需要每个正在运行的应用程序唯一的 id。他不想将此 id 硬编码到源代码中。此类问题可以通过为每个正在运行的应用程序设置的系统属性来解决(使用 -D 选项传递 id)。减号是因为...? 他想根据应用ID过滤传入的消息。在这种情况下,我仍然看不到属性有什么帮助(MDB selector 可以是注释或部署配置)。 @TK @Heenryk 你能描述一下如何用你的方法解决完整的问题吗?

以上是关于如何让我的 MDB 忽略来自自身的消息?的主要内容,如果未能解决你的问题,请参考以下文章

如何让我的 Vigenère Cipher 忽略原始消息中的空格

忽略来自 ajax url 的 http:localhost

log4net:配置为忽略来自特定类的消息

如何在idea中,忽略掉.gitignore文件自身,自己不能忽略自己,该怎么设置?

Python中的UDP套接字:如何清除缓冲区并忽略oldes消息

PL/SQL:忽略 SQL 语句?