【发布时间】:2019-04-15 16:00:08
【问题描述】:
我无法在骆驼中使用 CLIENT_ACKNOWLEDGE 模式确认 JMS 消息。在深入了解堆栈跟踪后,我发现 AbstractMessageListenerContainer 中的 message.acknowledge() 总是被执行,这会导致自动确认行为。是不是我配置错了?
org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(Session, Message)
protected void commitIfNecessary(Session session, Message message) throws JMSException {
// Commit session or acknowledge message.
if (session.getTransacted()) {
// Commit necessary - but avoid commit call within a JTA transaction.
if (isSessionLocallyTransacted(session)) {
// Transacted session created by this container -> commit.
JmsUtils.commitIfNecessary(session);
}
}
else if (message != null && isClientAcknowledge(session)) {
message.acknowledge();
}
}
弹簧配置
<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="cachedConnectionFactory" />
<property name="asyncConsumer" value="true" />
<property name="acknowledgementModeName" value="CLIENT_ACKNOWLEDGE" />
</bean>
<bean id="cachedConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="connectionFactory" />
<property name="sessionCacheSize" value="30" />
</bean>
骆驼路线
from(jmsTerminalRequest).routeId("generic-jms-inbound").setExchangePattern(ExchangePattern.InOnly).threads(5, 20, "generic-jms-inbound").bean(clientAckProcessor).to("...")
【问题讨论】:
-
有什么问题? camel-jms 使用具有自动确认功能的 spring。
-
问题出在客户端ack上。如果客户端确认在创建线程之前完成,它工作正常。即 from(jmsTerminalRequest).routeId("generic-jms-inbound").setExchangePattern(ExchangePattern.InOnly).bean(clientAckProcessor).threads(5, 20, "generic-jms-inbound").to("... ")
-
在 from JMX 端点上使用 concurrentConsumers=5&maxConcurrentConsumers=20 而不是线程(5,20),它应该可以工作
-
谢谢。但是,供应商仅提供不支持 maxConcurrentConsumers 选项的 JMS1.x 规范。无论您设置什么,它都只是在单线程中运行。
标签: jms apache-camel spring-jms