如何使用 Spring JMS 在 ActiveMQ 中创建多个侦听器

Posted

技术标签:

【中文标题】如何使用 Spring JMS 在 ActiveMQ 中创建多个侦听器【英文标题】:How to create multiple listeners in ActiveMQ using spring JMS 【发布时间】:2014-10-05 03:46:34 【问题描述】:

我有一个用例,我想在应用程序中创建多个侦听器 (6)。我想订阅多个目的地(6 个主题)。 所有订阅都是持久的。我为每个侦听器使用单独的默认消息侦听器容器(DMLC)并使用不同的客户端 ID,但我对如何使用连接工厂感到困惑。

我应该使用单个 ActiveMQ 池连接工厂并将 maxConnection 指定为 6。还是应该为每个侦听器使用不同的池连接工厂? 将 pooledConnectionFactory 和 maxConnection 用于持久订阅者有什么危害吗?

源代码: 连接工厂:

<bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL">
<value>$jms.broker.url</value>
</property>
</bean>
</property>
<property name="maxConnections" value="6" />

我的听众将其用作:(我有 6 个类似的听众,使用不同的目的地和客户端 ID)

<bean id="listenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer"

      <property name="connectionFactory" ref="jmsFactory" />
      <property name="destination" ref="topic_pnlCompleteTopic" />
      <property name="durableSubscriptionName" value="FAGCompletion" />
      <property name="pubSubDomain" value="true" />
      <property name="subscriptionDurable" value="$jms.fagsListener.durable" />
      <property name="clientId" value="$jms.fagsListener.clientId" />
      <property name="messageListener" ref="pnlMessageListener" />
      <property name="messageSelector" value="JMSType = 'FAG Completion'" />
 </bean>

【问题讨论】:

【参考方案1】:

只要您不将此连接工厂用于其他用途,这对我来说一切都很好。没有理由将连接数限制为 6,如果需要,您可以设置更高的数量,并且仅在必要时使用。 ConnectionFactory 通常是您为整个应用程序共享的内容。将其视为一种 DataSource 用于 JMS 访问

【讨论】:

正如您所说的“您没有将此连接工厂用于其他用途”。如果我在 JMStemplate 中使用它来创建生产者并在 DMLC 中使用它来创建消费者(如上所示)。如果我对 JMStemplate 和 DMLC 使用相同的连接工厂会导致问题吗? 正如你所说的“没有理由将连接数限制为 6”当我尝试使用少于 6 个连接时,它给了我以下错误,因为它是一个持久订阅者,每个订阅者应该有不同的连接的客户端 ID。 **org.springframework.jms.listener.DefaultMessageListenerContainer#refreshConnectionUntilSuccessful 875 WARN] - 无法刷新目标“topic://.seedTCAStatusPush”的 JMS 连接 - 5000 毫秒后重试。原因:不允许在使用的连接上设置 clientID **【参考方案2】:

由于您使用的是主题,因此您的听众通常每人只使用一个会话。没有理由对您的池指定限制或使用多个池。您通常会为您的应用程序使用一个池连接工厂,除非您有真正的理由将其限制或拆分到不同的池中。

【讨论】:

我必须对连接设置这个限制。如果我使用的连接少于 6 个,我会因为持久订阅者而收到此错误“**org.springframework.jms.listener.DefaultMessageListenerContainer#refreshConnect‌​ionUntilSuccessful 875 WARN] - 无法刷新目标 'topic://.seedTCAStatusPush 的 JMS 连接' - 在 5000 毫秒后重试。原因:不允许在已使用的连接上设置 clientID **" 你能回复一下吗? 我没有说你应该使用 less 小于 6。我只是说你的听众没有理由限制。 谢谢皮特。因此,即使我通过将 maxConnection 指定为所需值来为生产者(使用 JMS 模板)和消费者(使用 DMLC)使用相同的连接工厂。应该没问题吧? 没有。最大值是为了确保您的应用程序不会发疯并使用连接淹没 JMS 服务器。

以上是关于如何使用 Spring JMS 在 ActiveMQ 中创建多个侦听器的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring JMS 发布 JMS 主题?

如何使用spring boot jms收听话题

如何在spring集成消息中设置JMS Header

如何访问@JmsListener使用的Spring Boot中的活动JMS连接/会话

如何在spring boot中实现jms队列

如何使用 Spring JMS 在 ActiveMQ 中创建多个侦听器