摘要-系统关闭应用程序期间消息丢失。
我有一个用Spring集成编写的应用程序,并且正在使用'jms:message-driven-channel-adapter'来接收来自外部系统的请求。这是通道适配器的配置-
<jms:message-driven-channel-adapter id="InboundAdapter" destination="InQueue"
connection-factory="connectionFactory"
channel="responseChannel"
error-channel="errorChannel"
acknowledge="transacted"
receive-timeout="50000"
auto-startup="true"/>
我的回复频道如下所示-
<int:chain id="processorChain" input-channel="responseChannel">
<int:service-activator method="doProcess" ref="inputProcessor" />
<int:router id="inputRouter" method="route">
<int:mapping value="REQUIRED" channel="builderChannel"/>
<int:mapping value="NOT_REQUIRED" channel="TerminateChannel"/>
<bean id="Router" class="xxx.xxx.Router">
</bean>
</int:router>
</int:chain>
现在,当我执行“ kill -9 pid”时,我看到消息已回滚到队列,这一切都很好。但是当我执行“ kill pid”时,消息丢失了。我启用了jms日志,可以看到JMS侦听器在关闭JMS使用者之前正在等待传输中的消息完成,但是仍然没有消息回滚到我的队列中。这是我在日志中看到的日志片段
跟踪:15.11.18 15:42:46.619 [Thread-10]调试org.springframework.jms.listener.DefaultMessageListenerContainer-等待消息侦听器调用程序关闭 跟踪:15.11.18 15:42:46.619 [Thread-10]调试org.springframework.jms.listener.DefaultMessageListenerContainer-仍在等待关闭1个消息侦听器调用程序(迭代0)
此日志记录之后,它将调用在响应通道中定义的服务激活器。
有人可以说明上述行为吗?我期望当我们发出kill命令时,正在传输的所有消息都应回滚到队列中,而不是与此相反,它正在尝试调用定义为在频道中,并调用了路由器的最后一个组件后,它就结束了。
任何有关此主题的帮助将非常有帮助!
在进行了一些进一步的调试之后,我对系统进行了深入研究,我发现了发生这种情况的确切情况。让我直通看看是否有意义。当触发系统性关闭时,JMS将等待传输中的消息完成,然后再停止应用程序,直到此时一切都很好。目前,该链正在执行-
<int:chain input-channel="inputchain">
<int:transformer id="xxx" method="transform">
<bean class="xxx" />
</int:transformer>
<int:service-activator id="xxx" method="doProcess">
<bean class="xx">
<constructor-arg ref="xxx"/>
</bean>
</int:service-activator>
<int:service-activator id="xxx" ref="rulesProcessor" method="doProcess"/>
<int:service-activator id="xxx" ref="xxx" method="doProcess"/>
<!-- Existing Flow Continues -->
<int:router id="xxxRequiredRouter" method="xxxRequired">
<int:mapping value="Required" channel="firstChannel"/>
<int:mapping value="NotRequired" channel="secondChannel"/>
<bean id="xxxRouter" class="xxx.Router" />
</bean>
</int:router>
</int:chain>
<int:chain input-channel="secondChannel">
some logic
</int:chain>
因此线程完成了此链并正常退出。它没有将我的下一个链称为“ secondChannel”。我的交易边界未在此链“ inputchain”上完成,而是在secondChannel的末尾完成。因此,由于事务边界位于下一个链的末尾,因此我没有将这种转换提交给数据库,因此在数据库中不可用,并且应用程序认为链执行已完成,因此已完成,因此不会回滚到队列中。也一样因此,到最后,我的数据库中没有此消息,并且它不在队列中。
是这样的情况,只有关闭触发时正在执行的链会完成,并且不会将处理委托给后续链吗?
答案 0 :(得分:0)
杀死SIGTERM将等待线程完成其工作。
最终,容器会中断它,但这只会在它正在执行可中断的操作时有所帮助。