JMS 入站网关 - 回复目标队列发送不可能时的错误处理
JMS Inbound Gateway - error handling when reply destination queue send is not possible
我们有一个 EIP 流,它使用基于注释的 spring:4.2.x
API、spring-integration:4.2.x
API 和 spring-integration-java-dsl:1.1.0
API 从 Websphere MQ 队列接收消息,进行一些处理,最后 return 对另一个 Websphere MQ 队列的响应。对于此流程,我们使用 JMS Inbound Gateway
从一个队列同步接收消息,处理它们并将响应发送回另一个队列。
JMS Inbound Gateway
配置了 errorChannel
以便 RuntimeException
被路由到它(这工作正常)。但是在测试期间,当我们故意在流的响应 Websphere MQ 队列上应用 PUT_INHIBIT(即导致流无法将响应发送回回复队列)时,spring 日志显示以下内容WARNING
日志消息:
WARN ... - Execution of JMS message listener failed, and no ErrorHandler has been set.
javax.jms.JMSException: MQJMS2007: failed to send message to MQ queue.
我们知道我们可以通过在 MLC
本身上配置 ErrorHandler
来删除 WARNING
日志,但是,这给我们带来问题的原因是当我们将响应路由回去时,我们实际上使用 .routeToRecipients()
调用路由 .setIgnoreFailures(false)
和两个收件人 - 第一个收件人路由到 JMS Inbound Gateway
的 replyChannel
,第二个路由到 post-send 流程,以便我们可以进行数据库更新等。这里的想法是,如果第一个接收者发送失败(即当响应队列不可用时),post-send 流程不会执行但是而是执行错误处理流程(例如 errorChannel
流程)。但是在描述的错误场景中,我们看到了警告日志,并且流程的 post-send 流程仍然执行而不是 errorChannel
的流程...
就好像在这一点上,JMS Inbound Gateway
的 errorChannel
不再适用。这个对吗?这是预期的行为吗?如果是,这是否意味着我们应该使用 Inbound/Outbound Adapter
而不是 Inbound Gateway
来响应 post-发送意图?
JMS MLC 配置:
@Bean( destroyMethod = "shutdown")
public DefaultMessageListenerContainer serviceMLC() throws Exception {
DefaultMessageListenerContainer mlc = new DefaultMessageListenerContainer();
mlc.setAutoStartup(false);
mlc.setConnectionFactory(serviceCCF);
mlc.setDestination(requestMqQueue);
mlc.setAcceptMessagesWhileStopping(false);
return mlc;
}
JMS 入站网关配置:
@Bean
public IntegrationFlow serviceFlow() {
return IntegrationFlows
.from(Jms
.inboundGateway(serviceMLC)
.autoStartup(true)
.defaultReplyDestination(responseMqQueue)
.replyChannel(responseOutCh)
.replyTimeout(180000)
.correlationKey("JMSCorrelationID")
.errorChannel(serviceErrorCh)
)
.channel(serviceInCh)
.get();
}
是;网关不能那样工作。
当您将回复发送到网关时,它会在网关中排队,直到线程 returns 到达网关;届时,将接收并发送回复。因此,直到稍后(在调用第二个收件人流之后)才会发生发送失败。
是的,要执行您想要的操作,您应该改用通道适配器,因为失败将 运行 直接发生在调用线程上。
我们有一个 EIP 流,它使用基于注释的 spring:4.2.x
API、spring-integration:4.2.x
API 和 spring-integration-java-dsl:1.1.0
API 从 Websphere MQ 队列接收消息,进行一些处理,最后 return 对另一个 Websphere MQ 队列的响应。对于此流程,我们使用 JMS Inbound Gateway
从一个队列同步接收消息,处理它们并将响应发送回另一个队列。
JMS Inbound Gateway
配置了 errorChannel
以便 RuntimeException
被路由到它(这工作正常)。但是在测试期间,当我们故意在流的响应 Websphere MQ 队列上应用 PUT_INHIBIT(即导致流无法将响应发送回回复队列)时,spring 日志显示以下内容WARNING
日志消息:
WARN ... - Execution of JMS message listener failed, and no ErrorHandler has been set.
javax.jms.JMSException: MQJMS2007: failed to send message to MQ queue.
我们知道我们可以通过在 MLC
本身上配置 ErrorHandler
来删除 WARNING
日志,但是,这给我们带来问题的原因是当我们将响应路由回去时,我们实际上使用 .routeToRecipients()
调用路由 .setIgnoreFailures(false)
和两个收件人 - 第一个收件人路由到 JMS Inbound Gateway
的 replyChannel
,第二个路由到 post-send 流程,以便我们可以进行数据库更新等。这里的想法是,如果第一个接收者发送失败(即当响应队列不可用时),post-send 流程不会执行但是而是执行错误处理流程(例如 errorChannel
流程)。但是在描述的错误场景中,我们看到了警告日志,并且流程的 post-send 流程仍然执行而不是 errorChannel
的流程...
就好像在这一点上,JMS Inbound Gateway
的 errorChannel
不再适用。这个对吗?这是预期的行为吗?如果是,这是否意味着我们应该使用 Inbound/Outbound Adapter
而不是 Inbound Gateway
来响应 post-发送意图?
JMS MLC 配置:
@Bean( destroyMethod = "shutdown")
public DefaultMessageListenerContainer serviceMLC() throws Exception {
DefaultMessageListenerContainer mlc = new DefaultMessageListenerContainer();
mlc.setAutoStartup(false);
mlc.setConnectionFactory(serviceCCF);
mlc.setDestination(requestMqQueue);
mlc.setAcceptMessagesWhileStopping(false);
return mlc;
}
JMS 入站网关配置:
@Bean
public IntegrationFlow serviceFlow() {
return IntegrationFlows
.from(Jms
.inboundGateway(serviceMLC)
.autoStartup(true)
.defaultReplyDestination(responseMqQueue)
.replyChannel(responseOutCh)
.replyTimeout(180000)
.correlationKey("JMSCorrelationID")
.errorChannel(serviceErrorCh)
)
.channel(serviceInCh)
.get();
}
是;网关不能那样工作。
当您将回复发送到网关时,它会在网关中排队,直到线程 returns 到达网关;届时,将接收并发送回复。因此,直到稍后(在调用第二个收件人流之后)才会发生发送失败。
是的,要执行您想要的操作,您应该改用通道适配器,因为失败将 运行 直接发生在调用线程上。