How to stop message processing before undeploying?

后端 未结 1 2032
无人共我
无人共我 2021-01-15 07:47

Given:

  • A JMS message queue.
  • A timer service which puts messages to that queue periodically (from a database).
  • A JEE6 message
相关标签:
1条回答
  • 2021-01-15 08:21

    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.

    0 讨论(0)
提交回复
热议问题