如何在取消部署之前停止消息处理? [英] How to stop message processing before undeploying?

查看:16
本文介绍了如何在取消部署之前停止消息处理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于:

  • 一个 JMS 消息队列.
  • 一种定时服务,它定期(从数据库中)将消息放入该队列.
  • 从队列中读取的 JEE6 消息驱动 bean.
  • 计时器服务和消息驱动 Bean 是不同部署单元的一部分.

问题:

只要消息正在处理中,就不能在不破坏工作流状态的情况下取消部署消息驱动的 bean.因此,我们先停止定时器服务,等待所有消息完成.

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.

有没有办法使这种行为自动化?或者,如果计时器服务仍在运行,是否可以防止取消部署?我们目前使用的是 JBoss 4.2.3.

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.

非解决方案:

  • 重构部署单元,因为这会涉及多个部门.
  • 我知道系统崩溃不会被涵盖,而且防弹解决方案应该包括恢复策略.

推荐答案

每个部署的 MDB 都有一个 JMX 管理接口 MBean.此 MBean 的 ObjectName 因部署而异(并且也可能因 JBoss 版本而异).我使用的是 JBoss 4.3,ObjectName 格式是:

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:

Domain Name:    jboss.j2ee
service:    EJB3
name:   <MDB Name>
ear:    <EAR Name>  (if applicable)
jar:    <JAR Name>

如果您的计时器服务是 JBoss ServiceMBean,您可以使用 JBoss @Depends("the timer service ObjectName") 注释.这将强制计时器服务在 MDB 启动之前启动(因此最好使计时器服务有一些启动后延迟)但更重要的是,我相信在取消部署时会发生相反的情况,计时器服务应该先停止,然后是MDB.

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.

如果可行,它会负责排序,但我认为您不能在计时器运行时强制 MDB 不取消部署.您的应用程序的详细信息可能不支持这一点,但您可以考虑解决此问题的一种方法是使用 JBoss Quartz JCA Inflow Adapter 本质上将定时器和消息处理器绑定到一个(它就像一个 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.

================================尝试#2==================================

================================ Attempt #2 ================================

好的,所以您要防止 MDB 在馈送队列的深度大于零时停止.这种方法应该适用于您,尽管它高度特定于 JBoss.

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.

  1. 实现一个 JMX NotificationListener 监听状态MDB 委托 MBean 的更改.
  2. 您还可以实施 JMX NotificationFilter 以缩小您想收听的特定事件的范围.
  3. 您要查找的状态更改在属性 State 上,您要查找的转换是 3 --> 1 (开始 --> 停止)
  4. [此版本] JBoss 中的 JMX 通知是同步发出的,并且会一直阻塞,直到通知侦听器返回.当您的侦听器收到此通知时,在 MDB 的馈送队列 MBean 上启动轮询循环(没有询问您是否使用 JBoss Messaging,但我假设您使用了).当 MessageCount > 0 时,您将继续进行轮询.当队列的消息计数为零时,侦听器返回并且 MDB 将停止.
  5. 确保在轮询循环中添加一个短暂的睡眠,以及轮询超时(以防万一出现问题).
  6. 您也可以考虑在至少 n 个轮询循环的消息计数为 0 之前不返回,以防有一些未提交的消息在传输中可能不会出现在消息计数中.
  1. Implement a JMX NotificationListener that listens on state changes of the MDB Delegate MBean.
  2. You can also implement a JMX NotificationFilter to narrow down the specific events you want to listen on.
  3. The state change you're looking for is on the attribute State and the transition you're looking for is 3 --> 1 (Started --> Stopping)
  4. JMX notifications in [this version of] JBoss are issued synchronously and will block until the notification listener returns. When your listener receives this notification, start a polling loop on the MDB's feeding queue MBean (did not ask if you were using JBoss Messaging but I will assume you are). While the MessageCount is > 0, you keep polling. When the queue's message count is zero, the listener returns and the MDB will stop.
  5. Make sure to add a brief sleep in your polling loop, as well as a polling timeout (in case things get whacky).
  6. You might also consider not returning until the message count is 0 for at least n polling loops in case there is some uncommited message in transit which might not show up in the message count.

最重要的是,在调用您的属性更改侦听器时,将继续处理消息.当属性更改侦听器返回时,MDB 停止将继续.

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.

如果您的 JMS 实现是本地虚拟机内 JBoss Messaging,则队列消息计数将在队列的管理 MBean 中可用.对于任何其他设置,您可能需要进行专有的 JMS API 调用来获取队列的消息计数,或者,使用更强力的方法,您可以简单地请求 JMS QueueBrowser 并计算消息数.

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.

这篇关于如何在取消部署之前停止消息处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆