JmsOutboundGateway连接MQ超时设置及无限重试仍超时问题咨询
JmsOutboundGateway连接超时与无限重试失效问题
场景说明
当MQ管理器宕机时,JmsOutboundGateway会尝试连接MQ一段时间后释放线程/请求,当前存在两个核心疑问:
- 这个连接超时时间在哪里设置或查看?是否由
ConnectionFactory控制? - 已将
FixedBackOff设置为maxAttempts=unlimited,但请求仍会触发超时,原因是什么?
错误日志
org.springframework.integration.jms.JmsOutboundGateway$GatewayReplyListenerContainer handleListenerSetupFailure.940 ] - Setup of JMS message listener invoker failed for destination '' - trying to recover. Cause: null org.springframework.integration.jms.JmsOutboundGateway$GatewayReplyListenerContainer refreshConnectionUntilSuccessful.1007 ] - Could not refresh JMS Connection for destination '' - retrying using FixedBackOff{interval=5000, currentAttempts=2, maxAttempts=unlimited}. Cause: JMSWMQ0018: Failed to connect to queue manager 'LOCAL' with connection mode 'Client' and host name 'localhost(1415)'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE'). org.springframework.integration.jms.JmsOutboundGateway$GatewayReplyListenerContainer refreshConnectionUntilSuccessful.1007 ] - Could not refresh JMS Connection for destination '' - retrying using FixedBackOff{interval=5000, currentAttempts=3, maxAttempts=unlimited}. Cause: JMSWMQ0018: Failed to connect to queue manager 'LOCAL' with connection mode 'Client' and host name 'localhost(1415)'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE'). org.springframework.integration.dispatcher.UnicastingDispatcher logExceptionBeforeFailOver.185 ] - An exception was thrown by 'bean 'jmsOutbound...Gateway'; defined in: 'class path resource [/endpoints/GatewayConfig.class]'; from source: '.endpoints....jmsOutbound...Gateway(org.springframework.jms.connection.CachingConnectionFactory,org.springframework.integration.jms.JmsOutboundGateway$ReplyContainerProperties)'' while handling 'GenericMessage [payload= dummy message, headers={Persistence=0, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@20e63967, Format=MQSTR , errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@20e63967, Priority=4, messageId=[B@4569ec95, id=016d2bb2-9b03-aad8-2dd1-13cb92e6c42e, uuid=bf90a819-5430-49f8-8dd3-a23eb87e515f, timestamp=1710398153261}]': failed to handle a message in the [bean 'jmsOutboundGateway'; defined in: 'class path resource [.../endpoints/GatewayConfig.class]'; from source: 'com....configuration.endpoints.GatewayConfig.jmsOutbound...Gateway(org.springframework.jms.connection.CachingConnectionFactory,org.springframework.integration.jms.JmsOutboundGateway$ReplyContainerProperties)']; nested exception is com.ibm.msg.client.jms.DetailedIllegalStateException: JMSWMQ0018: Failed to connect to queue manager 'LOCAL' with connection mode 'Client' and host name 'localhost(1415)'. Check the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information.. Failing over to the next subscriber.
相关代码
消息网关定义
@MessagingGateway(name = "LocalGateway") public interface LocalGateway { @Gateway(requestChannel = "inputLocalChannel") ListenableFuture<Message<String>> sendMsg(Message<String> request); }
通道与网关配置
@Bean public MessageChannel inputLocalChannel(AsyncTaskExecutor gatewayReqExecutor) { return new ExecutorChannel(gatewayReqExecutor); } @Bean @ServiceActivator(inputChannel = "inputLocalChannel") public JmsOutboundGateway firstHandler(){ // 自定义配置代码 } @Bean @ServiceActivator(inputChannel = "inputLocalChannel") public JmsOutboundGateway secondHandler(){ // 自定义配置代码 }
问题解答
1. 连接超时的配置位置
这个超时不由JmsOutboundGateway本身控制,而是由底层MQ ConnectionFactory主导:
- 对于IBM MQ的
MQConnectionFactory,可通过setConnectionTimeout(int timeout)方法设置单次连接MQ的超时时间(单位毫秒)。 - 如果使用Spring的
CachingConnectionFactory包装MQ ConnectionFactory,超时配置需设置在被包装的原始MQ ConnectionFactory上,CachingConnectionFactory本身不处理连接超时逻辑。
你可以通过查看ConnectionFactory的初始化代码,或配置文件中对应的连接超时参数(如IBM MQ的connectionTimeout属性)确认当前设置。
2. FixedBackOff无限重试但请求仍超时的原因
日志中显示的FixedBackOff是GatewayReplyListenerContainer用于后台恢复连接的重试策略,和当前请求的处理生命周期无关:
- MQ宕机时,
JmsOutboundGateway发送请求阶段会先尝试建立连接,这个阶段的超时由ConnectionFactory的连接超时控制,一旦单次连接超时,请求会直接抛出异常触发失败转移(日志中的Failing over to the next subscriber可佐证)。 FixedBackOff的无限重试是监听容器在后台尝试恢复连接的逻辑,不会阻止当前请求因连接超时失败。
若需要让请求发送阶段也进行重试,需在JmsOutboundGateway上单独配置请求重试策略,比如通过setRetryTemplate(RetryTemplate retryTemplate)方法,结合FixedBackOff实现请求发送的无限重试。
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

