Apache Camel/ActiveMQ开启transacted=true后每秒生成DEBUG事务日志问题
问题:Apache Camel事务配置下空队列每秒生成DEBUG日志的原因
我是Apache Camel初学者,正在学习Manning出版的《Camel in Action》一书。按照第9章的说明配置了事务管理器,配置如下:
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://${activemq.host}:${activemq.port}" /> </bean> <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop"> <property name="maxConnections" value="2" /> <property name="connectionFactory" ref="jmsConnectionFactory" /> </bean> <bean id="jmsTxnManager" class="org.springframework.jms.connection.JmsTransactionManager"> <property name="connectionFactory" ref="pooledConnectionFactory" /> </bean> <bean id="activemq" class="org.apache.camel.component.activemq.ActiveMQComponent"> <property name="connectionFactory" ref="pooledConnectionFactory" /> <property name="transacted" value="true" /> <property name="transactionManager" ref="jmsTxnManager"/> </bean>
我还配置了一个简单的消费者路由:
<route id="exAroute"> <from uri="activemq:{{mq.in}}"/> <transacted/> <log message="${body}"/> </route>
当我运行Camel时,即使队列是空的,每秒都会生成一组DEBUG日志:
10:54:30.873 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.springframework.jms.connection.JmsTransactionManager - Creating new transaction with name [JmsConsumer[TEST_IN]]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 10:54:30.873 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.springframework.jms.connection.JmsTransactionManager - Created JMS transaction on Session [PooledSession { ActiveMQSession {id=ID:computer-60122-1666796067926-1:2:1,started=true} java.lang.Object@192cac46 }] from Connection [PooledConnection { ConnectionPool[ActiveMQConnection {id=ID:computer-60122-1666796067926-1:2,clientId=ID:computer-60122-1666796067926-0:1,started=true}] }] 10:54:31.885 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.activemq.ActiveMQMessageConsumer - remove: ID:computer-60122-1666796067926-1:2:1:2, lastDeliveredSequenceId: -1 10:54:31.885 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.springframework.jms.connection.JmsTransactionManager - Initiating transaction commit 10:54:31.885 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.springframework.jms.connection.JmsTransactionManager - Committing JMS transaction on Session [PooledSession { ActiveMQSession {id=ID:computer-60122-1666796067926-1:2:1,started=true} java.lang.Object@192cac46 }] 10:54:31.885 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.activemq.ActiveMQSession - ID:computer-60122-1666796067926-1:2:1 Transaction Commit :null 10:54:31.885 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.activemq.ActiveMQSession - ID:computer-60122-1666796067926-1:2:1 Transaction Rollback, txid:null
我想知道出现这种情况的原因是什么?我的配置是否存在错误?我已经花了2小时研究这个问题但没有进展,希望能得到帮助,提前感谢。
附:如果我向队列中放入消息,路由可以正常执行:
10:59:21.829 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.activemq.TransactionContext - Begin:TX:ID:computer-60151-1666796352835-1:2:1 10:59:21.829 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.camel.component.jms.DefaultJmsMessageListenerContainer - Received message of type [class org.apache.activemq.command.ActiveMQTextMessage] from consumer [PooledMessageConsumer { ActiveMQMessageConsumer { value=ID:computer-60151-1666796352835-1:2:1:5, started=true } }] of transactional session [PooledSession { ActiveMQSession {id=ID:computer-60151-1666796352835-1:2:1,started=true} java.lang.Object@296def58 }] 10:59:21.829 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.camel.component.jms.EndpointMessageListener - activemq://TEST_IN consumer received JMS message: ActiveMQTextMessage {commandId = 5, responseRequired = true, messageId = ID:computer-60156-1666796361583-1:1:1:1:1, originalDestination = null, originalTransactionId = null, producerId = ID:computer-60156-1666796361583-1:1:1:1, destination = queue://TEST_IN, transactionId = null, expiration = 0, timestamp = 1666796361809, arrival = 0, brokerInTime = 1666796361809, brokerOutTime = 1666796361819, 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@4db30c0e, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false, text = test} 10:59:21.859 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.camel.spring.spi.TransactionErrorHandler - Transaction begin (0x76adb233) redelivered(false) for (MessageId: ID:computer-60156-1666796361583-1:1:1:1:1 on ExchangeId: ID-computer-1666796353110-0-1)) 10:59:21.859 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.springframework.jms.connection.JmsTransactionManager - Participating in existing transaction 10:59:21.859 [Camel thread #2 - JmsConsumer[TEST_IN]] INFO exAroute - test 10:59:21.859 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.camel.spring.spi.TransactionErrorHandler - Transaction commit (0x76adb233) redelivered(false) for (MessageId: ID:computer-60156-1666796361583-1:1:1:1:1 on ExchangeId: ID-computer-1666796353110-0-1)) 10:59:21.859 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.springframework.jms.connection.JmsTransactionManager - Initiating transaction commit 10:59:21.859 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.springframework.jms.connection.JmsTransactionManager - Committing JMS transaction on Session [PooledSession { ActiveMQSession {id=ID:computer-60151-1666796352835-1:2:1,started=true} java.lang.Object@296def58 }] 10:59:21.859 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.activemq.ActiveMQSession - ID:computer-60151-1666796352835-1:2:1 Transaction Commit :TX:ID:computer-60151-1666796352835-1:2:1 10:59:21.859 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.activemq.TransactionContext - Commit: TX:ID:computer-60151-1666796352835-1:2:1 syncCount: 2 10:59:21.869 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.activemq.ActiveMQMessageConsumer - remove: ID:computer-60151-1666796352835-1:2:1:5, lastDeliveredSequenceId: 844 10:59:21.869 [Camel thread #2 - JmsConsumer[TEST_IN]] DEBUG org.apache.activemq.ActiveMQSession - ID:computer-60151-1666796352835-1:2:1 Transaction Rollback, txid:null
问题原因与解决方案
1. 根本原因:事务型消费者的短轮询机制
你配置的是事务型JMS消费者,当ActiveMQComponent设置transacted=true并关联JmsTransactionManager时,Camel底层使用的DefaultJmsMessageListenerContainer会默认采用短轮询策略:
- 每1秒启动一次事务,尝试从队列拉取消息
- 若队列无消息,事务会被提交,随后立即开启下一轮询
- 日志中的
Transaction Commit :null和Transaction Rollback, txid:null是空轮询后的正常事务收尾操作,并非错误,但会产生冗余DEBUG日志
2. 配置优化方案
(1)延长轮询间隔
在ActiveMQComponent中添加receiveTimeout参数,调整空队列时的轮询间隔,减少日志生成频率:
<bean id="activemq" class="org.apache.camel.component.activemq.ActiveMQComponent"> <property name="connectionFactory" ref="pooledConnectionFactory" /> <property name="transacted" value="true" /> <property name="transactionManager" ref="jmsTxnManager"/> <property name="receiveTimeout" value="5000"/> <!-- 设置为5秒轮询一次 --> </bean>
(2)启用长轮询
ActiveMQ支持长轮询,消费者会保持连接直到有消息或超时,避免频繁创建事务。只需在连接工厂的URL中添加useAsyncSend=true:
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://${activemq.host}:${activemq.port}?useAsyncSend=true" /> </bean>
(3)降低日志级别
如果只是不想看到DEBUG级别的事务日志,可在日志配置中将org.springframework.jms.connection.JmsTransactionManager和org.apache.activemq.ActiveMQSession的级别调整为INFO或WARN,过滤冗余输出。
3. 配置正确性说明
你的核心事务配置是正确的:
- 连接池、事务管理器与ActiveMQ组件的关联逻辑无误
- 消息能正常消费并提交事务,证明事务流程工作正常
空队列的日志只是轮询机制的副产品,不属于配置错误
内容的提问来源于stack exchange,提问作者burkheart14
相关产品推荐
相关产品推荐

