如何在取消部署之前停止消息处理?
给定:
- JMS 消息队列。
- 定时器服务定期将消息(从数据库)放入该队列。
- 从队列读取的 JEE6 消息驱动 bean。
- 计时器服务和消息驱动 bean 是不同部署单元的一部分。
问题:
只要消息正在处理中,就无法在不破坏工作流状态的情况下取消部署消息驱动 Bean。因此,我们首先停止计时器服务并等待所有消息完成。
有没有办法使这种行为自动化?或者如果计时器服务仍在运行,是否可以防止取消部署?我们目前使用的是 JBoss 4.2.3。
非解决方案:
- 重构部署单元,因为这会涉及多个部门。
- 我知道系统崩溃不会被涵盖,并且防弹解决方案应该包括恢复策略。
Given:
- A JMS message queue.
- A timer service which puts messages to that queue periodically (from a database).
- A JEE6 message-driven bean which reads from the queue.
- The timer service and the message-driven bean are part of different deployment units.
Problem:
The message-driven bean cannot be undeployed, without breaking the workflow state, as long as messages are work in process. Because of that, we stop the timer service first and wait until all messages are finished.
Is there a way to automate that behavior? Or is it possible to prevent undeployment if the timer service is still running? We are currently using JBoss 4.2.3.
Non-Solutions:
- Refactoring the deployment units, because it would involve several departments.
- I know that a system crash won't be covered and that a bulletproof solution should include a recovery strategy.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
每个部署的 MDB 都有一个 JMX 管理接口 MBean。此 MBean 的 ObjectName 根据部署的不同而有所不同(并且 JBoss 版本之间也可能有所不同)。我使用的是 JBoss 4.3,ObjectName 格式为:
如果您的计时器服务是 JBoss ServiceMBean,您可以使用 JBoss 让您的 MDB 依赖 于计时器@Depends("定时器服务ObjectName")注释。这将强制计时器服务在 MDB 启动之前启动(因此最好让计时器服务有一些启动后延迟),但更重要的是,我相信在取消部署时会发生相反的情况,并且计时器服务应该首先停止,然后是 MDB。
如果有效,它会负责排序,但我认为您不能强制 MDB 在计时器运行时不取消部署。您的应用程序的详细信息可能不支持这一点,但您可能考虑解决此问题的一种方法是使用 JBoss Quartz JCA Inflow Adapter 本质上将定时器和消息处理器绑定到一个(它就像一个 MDB,但它接收定时器事件而不是消息),让您摆脱解决两个组件之间的依赖关系。
=================================
尝试#2
================================
好的,所以您想防止 MDB 在馈送队列有深度时停止大于零。这种方法应该适合您,尽管它是针对 JBoss 的。
最重要的是,当您的属性更改侦听器被调用时,消息将继续被处理。当属性更改侦听器返回时,MDB 停止将继续。
如果您的 JMS 实现是本地 VM 内 JBoss Messaging,则队列消息计数将在队列的管理 MBean 中可用。对于任何其他设置,您可能需要进行专有的 JMS API 调用来获取队列的消息计数,或者使用更强力的方法,您可以简单地请求 JMS QueueBrowser 并计算消息数。
Each deployed MDB has a JMX management interface MBean. The ObjectName of this MBean varies according to deployment (and might also be different between versions of JBoss). I am using JBoss 4.3 and the ObjectName format is:
If your timer service is a JBoss ServiceMBean, you can make your MDB depend on the timer by using the JBoss @Depends("the timer service ObjectName") annotation. This will force the timer service to start before the MDB starts (so preferably, make the timer service have some post start delay) but more importantly, I believe the reverse will occur on undeploy and the timer service should stop first, then the MDB.
If that works, it takes care of ordering, but I don't think you can force the MDB not undeploy while the timer is running. The details of your application might not support this, but one way you might consider resolving this issue is to use the JBoss Quartz JCA Inflow Adapter which will essentially bind the timer and message processor into one (it's like an MDB, but it receives timer events rather than messages), ridding you of having to wrestle with dependencies between two components.
================================
Attempt #2
================================
Ok, so you want to prevent the MDB from stopping while the feeding queue has a depth of more than zero. This approach should work for you, although it is highly specific to JBoss.
The bottom line is that while your attribute change listener is being called, message will continue to be processed. When the attribute change listener returns, the MDB stop will continue.
If your JMS implementation is the local in-VM JBoss Messaging, the queue message count will be available in the queue's management MBean. For any other setup, you may need to make a proprietary JMS API call to get the queue's message count, or, using a more brute force approach, you can simply request a JMS QueueBrowser and count the number of messages.