3

我有一个使用 Spring MessageListenerContainers 和 ActiveMQ 的应用程序。按照 activemq 的文档,我已将其配置为使用 PooledConnectionFactory。

我的情况如下:

  • 来自队列的两个 java-app 消费者(2 个不同的 tomcat)
  • 主从 activemq 代理,带有故障转移 url
  • PooledConnectionFactory 已配置
  • 应用程序上的骆驼
  • activemq 5.8.0,带有commons-pool 1.6

一切似乎都正常,但有时消息会重新传递给消费者,这会导致应用程序错误。

根据日志,我怀疑此错误是由 spring 的 PooledConnectionFactory bean 定义中的一些错误配置引起的,该定义甚至关闭了已使用的连接,然后强制回滚当前会话,从而重新传递消息

池的弹簧配置如下:

<bean id="AMQconnFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL">
            <value>${activemq_url}?initialReconnectDelay=100&amp;timeout=3000&amp;jms.prefetchPolicy.all=1&amp;jms.redeliveryPolicy.initialRedeliveryDelay=300000
            </value>
        </property>
    </bean>
    <bean id="sharedConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" abstract="true">
        <property name="connectionFactory" ref="AMQconnFactory" />
        <property name="maxConnections" value="30" />
    </bean>

    <bean id="MotionJMSConnectionFactory" parent="sharedConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
        init-method="start" destroy-method="stop" />

<bean id="sharedListenersProps" abstract="true" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="maxConcurrentConsumers" value="1" />
        <property name="concurrentConsumers" value="1" />
        <property name="connectionFactory" ref="MotionJMSConnectionFactory" />
        <property name="sessionTransacted" value="true" />
        <property name="transactionTimeout" value="300"/>
    </bean>

将我指向该方向的日志如下:

[TRACE] (ActiveMQMessageConsumer.java:494) (09:48:16,412) - ID:bbiovx01.bglobal.bcorp-56155-1365791814916-1:3222:1:1 received message: MessageDispatch {commandId = 0, responseRequired = false, consumerId = 
ID:bbiovx01.bglobal.bcorp-56155-1365791814916-1:3222:1:1, destination = queue://EntradaQueue, message = ActiveMQObjectMessage {commandId = 12999, responseRequired = true, messageId = ID:bbiovx01.bglobal.bco
rp-33973-1365792268762-1:28:2:1:12, originalDestination = null, originalTransactionId = null, producerId = ID:bbiovx01.bglobal.bcorp-33973-1365792268762-1:28:2:1, destination = queue://EntradaQueue, transac
tionId = null, expiration = 0, timestamp = 1365857296363, arrival = 0, brokerInTime = 1365857296364, brokerOutTime = 1365857296410, correlationId = null, replyTo = null, persistent = true, type = null, prio
rity = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@31efa8c3, marshalledProperties = null, dataStructure 
= null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false}, redeliveryCounter = 0}
[DEBUG] (AbstractPollingMessageListenerContainer.java:313) (09:48:16,412) - Received message of type [class org.apache.activemq.command.ActiveMQObjectMessage] from consumer [PooledMessageConsumer { ActiveMQ
MessageConsumer { value=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-1:3222:1:1, started=true } }] of session [PooledSession { ActiveMQSession {id=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-1:3222:1,sta
rted=true} }]
<!-- app LOG -->
[DEBUG] (MDPEntrada.java:53) (09:48:16,413) - Mensagem de entrada recebida ActiveMQObjectMessage {commandId = 12999, responseRequired = true, messageId = ID:bbiovx01.bglobal.bcorp-33973-1365792268762-1:28:2:1:12, originalDestination = null, originalTransactionId = null, producerId = ID:bbiovx01.bglobal.bcorp-33973-1365792268762-1:28:2:1, destination = queue://EntradaQueue, transactionId = null, expiration = 0, timestamp = 1365857296363, arrival = 0, brokerInTime = 1365857296364, brokerOutTime = 1365857296410, correlationId = null, replyTo = null, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@31efa8c3, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false}
TRACE] (PooledConnectionFactory.java:121) (09:48:17,295) - Destroying connection: ConnectionPool[null]
[TRACE] (PooledConnectionFactory.java:154) (09:48:17,295) - Connection has expired: ConnectionPool[null] and will be destroyed
[TRACE] (PooledConnectionFactory.java:121) (09:48:17,295) - Destroying connection: ConnectionPool[null]
[TRACE] (PooledConnectionFactory.java:154) (09:48:17,296) - Connection has expired: ConnectionPool[ActiveMQConnection {id=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-1:3222,clientId=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-0:3218,started=true}] and will be destroyed
[TRACE] (PooledConnectionFactory.java:121) (09:48:17,296) - Destroying connection: ConnectionPool[ActiveMQConnection {id=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-1:3222,clientId=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-0:3218,started=true}]
[TRACE] (PooledConnectionFactory.java:154) (09:48:17,297) - Connection has expired: ConnectionPool[ActiveMQConnection {id=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-1:3221,clientId=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-0:3217,started=true}] and will be destroyed
[TRACE] (PooledConnectionFactory.java:121) (09:48:17,297) - Destroying connection: ConnectionPool[ActiveMQConnection {id=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-1:3221,clientId=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-0:3217,started=true}]
[WARN ] (PooledSession.java:123) (09:48:17,297) - Caught exception trying rollback() when putting session back into the pool, will invalidate. javax.jms.IllegalStateException: The Session is closed
javax.jms.IllegalStateException: The Session is closed
        at org.apache.activemq.ActiveMQSession.checkClosed(ActiveMQSession.java:731)
        at org.apache.activemq.ActiveMQSession.rollback(ActiveMQSession.java:574)
        at org.apache.activemq.pool.PooledSession.close(PooledSession.java:120)
        at org.springframework.jms.support.JmsUtils.closeSession(JmsUtils.java:108)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.clearResources(DefaultMessageListenerContainer.java:1099)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:958)
        at java.lang.Thread.run(Thread.java:662)
[WARN ] (DefaultMessageListenerContainer.java:818) (09:48:17,297) - Setup of JMS message listener invoker failed for destination 'topic://AtualizaAssinaturasETemplatesTopic' - trying to recover. Cause: The Session is closed
javax.jms.IllegalStateException: The Session is closed
        at org.apache.activemq.ActiveMQSession.checkClosed(ActiveMQSession.java:731)
        at org.apache.activemq.ActiveMQSession.getTransacted(ActiveMQSession.java:521)
        at org.apache.activemq.pool.PooledSession.getTransacted(PooledSession.java:259)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(AbstractMessageListenerContainer.java:571)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:358)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1059)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)
        at java.lang.Thread.run(Thread.java:662)
[TRACE] (PooledConnectionFactory.java:154) (09:48:17,302) - Connection has expired: ConnectionPool[null] and will be destroyed
[TRACE] (PooledConnectionFactory.java:121) (09:48:17,302) - Destroying connection: ConnectionPool[null]
[TRACE] (PooledConnectionFactory.java:154) (09:48:17,302) - Connection has expired: ConnectionPool[null] and will be destroyed
[TRACE] (PooledConnectionFactory.java:121) (09:48:17,303) - Destroying connection: ConnectionPool[null]
[TRACE] (PooledConnectionFactory.java:140) (09:48:17,303) - Created new connection: ConnectionPool[ActiveMQConnection {id=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-1:3320,clientId=null,started=false}]
[INFO ] (DefaultMessageListenerContainer.java:862) (09:48:17,306) - Successfully refreshed JMS Connection
[INFO ] (SEntradaImpl.java:368) (09:48:17,311) - Tempo de Processamento da requisicao: 843ms
[INFO ] (SEntradaImpl.java:227) (09:48:17,311) - * FINALIZANDO ENTRADA *
[WARN ] (AbstractMessageListenerContainer.java:694) (09:48:17,312) - Execution of JMS message listener failed, and no ErrorHandler has been set.
javax.jms.IllegalStateException: The Session is closed
        at org.apache.activemq.ActiveMQSession.checkClosed(ActiveMQSession.java:731)
        at org.apache.activemq.ActiveMQSession.getTransacted(ActiveMQSession.java:521)
        at org.apache.activemq.pool.PooledSession.getTransacted(PooledSession.java:259)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(AbstractMessageListenerContainer.java:571)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:481)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1059)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)
        at java.lang.Thread.run(Thread.java:662)
[WARN ] (PooledSession.java:123) (09:48:17,312) - Caught exception trying rollback() when putting session back into the pool, will invalidate. javax.jms.IllegalStateException: The Session is closed
javax.jms.IllegalStateException: The Session is closed
        at org.apache.activemq.ActiveMQSession.checkClosed(ActiveMQSession.java:731)
        at org.apache.activemq.ActiveMQSession.rollback(ActiveMQSession.java:574)
        at org.apache.activemq.pool.PooledSession.close(PooledSession.java:120)
        at org.springframework.jms.support.JmsUtils.closeSession(JmsUtils.java:108)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.clearResources(DefaultMessageListenerContainer.java:1099)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:958)
        at java.lang.Thread.run(Thread.java:662)
[WARN ] (DefaultMessageListenerContainer.java:818) (09:48:17,312) - Setup of JMS message listener invoker failed for destination 'queue://EntradaQueue' - trying to recover. Cause: The Session is closed
javax.jms.IllegalStateException: The Session is closed
        at org.apache.activemq.ActiveMQSession.checkClosed(ActiveMQSession.java:731)
        at org.apache.activemq.ActiveMQSession.getTransacted(ActiveMQSession.java:521)
        at org.apache.activemq.pool.PooledSession.getTransacted(PooledSession.java:259)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(AbstractMessageListenerContainer.java:571)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:481)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1059)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)
        at java.lang.Thread.run(Thread.java:662)
[TRACE] (PooledConnectionFactory.java:140) (09:48:17,312) - Created new connection: ConnectionPool[ActiveMQConnection {id=ID:bbiovx01.bglobal.bcorp-56155-1365791814916-1:3322,clientId=null,started=false}]
[INFO ] (DefaultMessageListenerContainer.java:862) (09:48:17,316) - Successfully refreshed JMS Connection

如果需要,我可以提供更多细节。

此致。

编辑:

另外,我尝试将池大小减少到 1,现在,我更经常地收到以下堆栈(警告):

[WARN ] (PooledSession.java:123) (02:00:00,160) - Caught exception trying rollback() when putting session back into the pool, will invalidate. javax.jms.IllegalStateException: The Session is closed
javax.jms.IllegalStateException: The Session is closed
    at org.apache.activemq.ActiveMQSession.checkClosed(ActiveMQSession.java:731)
    at org.apache.activemq.ActiveMQSession.rollback(ActiveMQSession.java:574)
    at org.apache.activemq.pool.PooledSession.close(PooledSession.java:120)
    at org.springframework.jms.support.JmsUtils.closeSession(JmsUtils.java:108)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.clearResources(DefaultMessageListenerContainer.java:1099)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:958)
    at java.lang.Thread.run(Thread.java:662)
[WARN ] (PooledSession.java:123) (02:00:00,160) - Caught exception trying rollback() when putting session back into the pool, will invalidate. javax.jms.IllegalStateException: The Session is closed
javax.jms.IllegalStateException: The Session is closed
    at org.apache.activemq.ActiveMQSession.checkClosed(ActiveMQSession.java:731)
    at org.apache.activemq.ActiveMQSession.rollback(ActiveMQSession.java:574)
    at org.apache.activemq.pool.PooledSession.close(PooledSession.java:120)
    at org.springframework.jms.support.JmsUtils.closeSession(JmsUtils.java:108)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.clearResources(DefaultMessageListenerContainer.java:1099)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:958)
    at java.lang.Thread.run(Thread.java:662)
4

2 回答 2

7

这是由 PooledConnection 代码中的错误引起的,将在版本 5.9.0 中修复。一种解决方法是将 PooledConnectionFactory 上的空闲超时设置为 0。

PooledConnectionFactory.setIdleTimeout(0)
于 2013-04-14T10:12:07.217 回答
-1

添加属性

<property name="idleTimeout" value="0"/>

到您的 PooledConnectionFactory

于 2013-12-07T23:56:18.707 回答