Java JMS入站网关-无法发送回复目标队列时的错误处理
我们有一个EIP流,它使用基于注释的Java JMS入站网关-无法发送回复目标队列时的错误处理,java,spring,spring-integration,spring-jms,Java,Spring,Spring Integration,Spring Jms,我们有一个EIP流,它使用基于注释的spring:4.2.xAPI、spring集成:4.2.xAPI和spring集成java dsl:1.1.0API从Websphere MQ队列接收消息,进行一些处理,最后将响应返回到另一个Websphere MQ队列。对于这个流,我们使用JMS入站网关从一个队列同步接收消息,处理它们并将响应发送回另一个队列 JMS入站网关配置了一个errorChannel,以便将RuntimeExceptions路由到它(这可以正常工作)。但是,在测试期间,当我们有意对
spring:4.2.x
API、spring集成:4.2.x
API和spring集成java dsl:1.1.0
API从Websphere MQ队列接收消息,进行一些处理,最后将响应返回到另一个Websphere MQ队列。对于这个流,我们使用JMS入站网关
从一个队列同步接收消息,处理它们并将响应发送回另一个队列
JMS入站网关
配置了一个errorChannel
,以便将RuntimeException
s路由到它(这可以正常工作)。但是,在测试期间,当我们有意对流的响应Websphere MQ队列应用PUT_INHIBIT(即,导致流无法将响应发送回应答队列)时,spring日志显示以下警告日志消息:
警告…-执行JMS消息侦听器失败,未设置ErrorHandler。
javax.jms.JMSException:MQJMS2007:未能将消息发送到MQ队列。
我们知道我们可以通过在MLC
本身上配置ErrorHandler
来删除警告
日志,但是,这会给我们带来问题的原因是,当我们回传响应时,我们实际上使用.routeToRecipients()
调用.setIgnoreFailures(false)进行路由
和两个接收者-第一个接收者路由到JMS入站网关
的replyChannel
,第二个路由到发送后流,以便我们可以进行数据库更新等。这里的想法是,如果第一个接收者发送失败(即,当响应队列不可用时),发送后流程不执行,而是执行错误处理流程(例如errorChannel
flow)。但是在所描述的错误场景中,我们看到警告日志,流的发送后流仍然执行,而不是errorChannel
的流
此时,似乎JMS入站网关的errorChannel
不再适用。这是正确的吗?这是故意的行为吗?如果是,这是否意味着我们应该使用入站/出站适配器
s而不是入站网关
来实现发送后的响应意图
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;
}
@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();
}
JMS入站网关配置:
@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;
}
@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();
}
对,;网关不是那样工作的
当您向网关发送回复时,它将在网关中排队,直到线程返回网关;此时,将拾取并发送回复。因此,发送失败直到稍后才会发生(在调用第二个收件人流之后)
是的,要执行您想要的操作,您应该改用通道适配器,因为故障将直接在调用线程上运行。您能指出一个使用Java类的示例吗?(不是bean-config-xml)您不应该在对(非常)旧的答案的评论中提出无关的问题。你问的问题也一点也不清楚——什么样的问题?问一个更清晰的新问题。这不是无关的。您接受的答案没有提供任何使用@Bean在Java中执行的示例链接,仅此而已,但它就在问题中(@Bean
)。就像我说的,问一个更详细的新问题将有助于人们准确地理解你需要什么帮助。堆栈溢出不适用于扩展注释(管理员不鼓励这样做)。