【问题标题】:ActiveMQ Spring listener suddently stops workingActiveMQ Spring 监听器突然停止工作
【发布时间】:2015-03-12 23:37:32
【问题描述】:

我必须修复从另一家公司继承的应用程序,我有一个我不清楚的错误:jms 侦听器突然停止工作,没有任何明显的原因。

这是一个基于spring的客户端,这里是上下文:

    <bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" >
    <property name="useAsyncSend" value="false" />
    <property name="useCompression" value="true" />
    <property name="optimizeAcknowledge" value="true" />
    <property name="messagePrioritySupported" value="true" />
    <property name="brokerURL" value="failover:(tcp://${brokerHost}:61616)?timeout=3000&jms.redeliveryPolicy.maximumRedeliveries=-1&jms.redeliveryPolicy.maximumRedeliveryDelay=1000000&jms.redeliveryPolicy.useExponentialBackOff=true" />
    <property name="maxThreadPoolSize" value="60" />
    <property name="closeTimeout" value="2000" />
    <property name="nonBlockingRedelivery" value="true" />
    <property name="exclusiveConsumer" value="false" />
</bean>

<bean id="jmsConnectionFactory"  class="org.apache.activemq.pool.PooledConnectionFactory" >
    <property name="connectionFactory" ref="amqConnectionFactory" /> 
    <property name="maxConnections" value="50" />
    <property name="maximumActiveSessionPerConnection" value="100" />
    <property name="idleTimeout" value="20000" />
    <property name="expiryTimeout" value="15000" />
</bean>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" abstract="true">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
    <property name="explicitQosEnabled" value="true"/>
    <property name="sessionTransacted" value="true" />
    <property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE" />
    <property name="receiveTimeout" value="4000" />
</bean>

<bean id="actionsJmsTemplate" parent="jmsTemplate">
    <property name="defaultDestination" ref="actionPendingDestination"/>
</bean>

<bean id="jmsActionsListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
    <property name="destination" ref="actionPendingDestination"/>
    <property name="messageSelector" value="" />
    <property name="messageListener" ref="actionsListener" />
    <property name="sessionTransacted" value="true"/>
    <property name="cacheLevelName" value="CACHE_SESSION" />
    <property name="maxConcurrentConsumers" value="50" />
    <!-- <property name="transactionManager" ref="transactionManager" /> -->
    <property name="transactionTimeout" value="1000" />
</bean>

<!--  ActiveMQ Destinations -->
<bean id="actionPendingDestination" class="org.apache.activemq.command.ActiveMQQueue">
    <constructor-arg index="0" value="actions.pending.queue.>"/>

处理应用程序内部消息的 bean“actionsListener”实现了 javax.jms.MessageListener 和 org.springframework.beans.factory.BeanNameAware。它不会做任何事情,比如确认会话或管理事务。那个类中没有这样的代码。

库的版本是:

  • 春季:3.2.5.RELEASE
  • ActiveMQ 客户端:5.9
  • JDK:1.6

你觉得这个配置有什么问题吗?

谢谢!

卡洛斯

【问题讨论】:

  • 在停止工作之前处理了多少条消息?

标签: java spring activemq


【解决方案1】:

我看到它正在使用 CLIENT_ACKNOWLEDGE;您是否确认 ack 发生在所有代码路径(包括异常)上?已经有一段时间了,但我认为如果你不确认消息会发生什么,你只能处理你的预取缓冲区值,所以一旦你没有做出那个数量的确认,你就完成了。

【讨论】:

  • 这就是我的怀疑,尽管我不确定 Spring 是否以某种方式处理了这个问题。另外,正如您所看到的,会话已被处理,我不确定这是否会影响确认模式...一旦我们可以启动系统,我将查看完美缓冲区,这只发生在生产,所以有点棘手:S 谢谢!
  • 如果您能找到一种方法在测试环境中始终如一地重现它,您可以尝试将 ack 模式设置为 AUTO_ACK 以查看是否解决了问题。 (这至少可以确认问题是否是未能确认消息。)
  • 如何检查消费者的预取缓冲区大小?此外,具有完整预取缓冲区的消费者是否算作并发消费者?如果是这样,如果只有 10 个消费者的缓冲区已满,他们就会阻止消息消费。
  • 您可以使用 JMX 查看器(例如 JConsole)查看给定消费者的已调度消息数;如果消息在 broker 上备份,那么您知道客户端的预取缓冲区已满,因此当前分派给它的消息数量等于其预取缓冲区大小。
猜你喜欢
  • 2015-05-27
  • 1970-01-01
  • 1970-01-01
  • 2019-02-19
  • 2016-04-29
  • 1970-01-01
  • 1970-01-01
  • 2017-08-22
  • 2021-02-01
相关资源
最近更新 更多