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

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

问题描述

给定:




  • JMS消息队列。

  • 一个定时器服务,将消息定期(从数据库)发送到该队列。

  • 从队列中读取的JEE6消息驱动的bean。

  • 定时器服务和消息驱动的bean是不同部署单元的一部分。



问题: p>

只要消息正在进行中,消息驱动的bean就不能取消部署,而不会中断工作流状态。因此,我们先停止定时服务,等待所有消息完成。



有没有办法自动执行该行为?或者如果定时器服务仍在运行,是否可以防止取消部署?我们正在使用JBoss 4.2.3。



非解决方案:




  • 重新构建部署单元,因为它涉及到几个部门。

  • 我知道系统崩溃不会被覆盖,而一个防弹解决方案应该包括恢复策略。


解决方案

每个部署的MDB都有一个JMX管理界面MBean。该MBean的ObjectName根据部署而有所不同(并且JBoss版本之间也可能不同)。我使用JBoss 4.3,ObjectName格式是:

 域名:jboss.j2ee 
服务:EJB3
名称:< MDB名称>
耳朵:< EAR名称> (如果适用)
jar:< JAR名称>

如果您的定时服务是JBoss ServiceMBean,您可以使您的MDB 依赖 使用JBoss @Depends(定时器服务ObjectName)注释定时器。这将强制定时器服务在MDB启动之前启动(因此,最好使定时器服务有一些后启动延迟),但更重要的是,我相信相反将在undeploy上发生,定时器服务应该先停止,然后MDB。



如果这样工作,它负责订购,但是我不认为您可以在定时器运行时强制MDB不取消部署。您的应用程序的详细信息可能不支持此功能,但您可能会考虑解决此问题的一种方法是使用 JBoss Quartz JCA Inflow适配器,它将基本上将定时器和消息处理器绑定到一个(它就像一个MDB,但它接收定时器事件而不是消息),避免你有与两个组件之间的依赖关系搏斗。



======================= =====
尝试#2
============================== p>

好的,所以你想防止MDB停止,而进料队列的深度大于零。这个方法应该适用于你,虽然它对JBoss非常具体。


  1. 实现一个 JMX NotificationListener

  2. 您还可以实现 JMX NotificationFilter 缩小您想要收听的具体事件。

  3. 您正在查找的状态更改属于状态您正在寻找的转换是 3 - > 1 开始 - >停止

  4. [本版本] JBoss中的JMX通知将同步发出,并将阻止,直到通知侦听器返回。当您的收听者收到此通知时,在MDB的馈送队列MBean上启动轮询循环(没有询问您是否使用JBoss Messaging,但我会假设您是)。当 MessageCount > 0时,您继续轮询。当队列的消息计数为零时,监听器返回,MDB将停止。

  5. 确保在轮询循环中添加一个简短的睡眠,以及轮询超时(如果事件

  6. 您可能还会考虑在消息计数为0以前,至少为了 n 轮询循环,以防传输中有一些未通知的消息可能不会显示在消息计数中。

底线是当您的属性更改侦听器被调用时,消息将继续被处理。当属性更改监听器返回时,MDB停止将继续。



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


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.

解决方案

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>

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.

  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.

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.

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

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