我们运行大约80个批处理作业的序列,其中一半以上分区最多50个分区。据我所知,我们唯一的非标准做法是禁用自动启动。网关的启动和停止由步骤监听器管理。这在大多数时间都没问题,但我们偶尔会看到失败。我增加了日志记录并查看了使用correlationId发送的所有消息。堆栈跟踪发生在远程分区结束后(在这种情况下......大约3分钟):
2016-01-19 22:19:01,517 DEBUG [org.springframework.integration.jms.JmsOutboundGateway] (springbatch.partitioned.jms.taskExecutor-38) policy.estimatepayroll.outbound-gateway Sending message with correlationId d1025dfd-3551-4df8-96a7-043364c52e3d_18
2016-01-19 22:21:55,240 WARN [org.springframework.integration.jms.JmsOutboundGateway] (org.springframework.integration.jms.JmsOutboundGateway#0.replyListener-1) Failed to consume reply with correlationId d1025dfd-3551-4df8-96a7-043364c52e3d_18
java.lang.RuntimeException: No sender waiting for reply
at org.springframework.integration.jms.JmsOutboundGateway.onMessage(JmsOutboundGateway.java:945)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:562)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:500)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:468)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:326)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:264)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1069)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1061)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:958)
at java.lang.Thread.run(Unknown Source)
问题在于,当发生这种情况时,onMessage()方法会抛出一个杀死线程的RuntimeException。后续作业使用的线程较少,因此某些分区是串行执行而不是并行执行。
我已经查看了代码,但无法找到这个问题怎么发生?可能是因为回复是HashMap而不是线程安全吗?
感谢您提供任何帮助/建议。
答案 0 :(得分:2)
最可能的原因是receive-timeout
太低 - 因此发送线程超时并且不再等待回复。
默认超时非常低(5秒)。
修改强>
很抱歉,忘了这是最近修复的(在4.2和4.1中)。
我们已经使用修复程序反向移植但尚未发布4.0.x或3.0.x.