在JBoss 6.0中延迟启动JMS侦听器(MDB)

时间:2012-02-13 14:38:33

标签: jboss jms ejb-3.1 hornetq jboss-mdb

我们在集群环境中有多个JBoss-Server实例。对于后台任务,有一个可用的全局队列,用于管理在其上注册的所有作业。对于此队列,每个节点上都有一个简单的侦听器(MDB),用于管理传入的消息。此侦听器对单例bean执行手动查找(无注入)并启动预定义的方法。 到目前为止一切正常,但是单例bean中的方法使用了在某些情况下不可用的其他(没有单例服务)。 例如,如果节点将重新启动并且队列中有剩余消息(尚未处理),则侦听器将拾取消息,并且所有其他bean都为空,因此作业将生成NPE。 是否可以在拾取消息后在JMS-Listener中定义延迟时间,或者是否可以在其中定义“应用程序完全部署”挂钩?由于非单身人士的使用,DependsOn-Annotation不起作用。

可能的情况是将MDB属性“DeliveryActive”设置为false并在完全部署后启动bean。是否有一种简单,有效的方式以编程方式执行此操作(而不是在jmx-console中)?我找到的任何手册都会将我重定向到手动jndi查找。我认为必须能够为每个注释注入Bean并调用startDelivery()吗?在申请中有这个好地方吗?

另一个提示将我带到application.xml中的order属性的初始化,因为问题可能与JBoss部署顺序相关(某些EJB稍后可用于侦听器),但似乎有{{3}并升级到6.1。不是一种选择。也许有一个演练呢?

我希望问题解释得很好,否则请询问进一步的信息。

提前致谢, 丹尼

其他信息:

  • JBoss 6.0.0 Final
  • HornetQ 2.2.5 Final(已更新,因为JBoss的默认版本)

听众:

@MessageDriven(activationConfig =
    {
            @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
            @ActivationConfigProperty(propertyName = "destination", propertyValue = "/queue/SchedulerQueue")
    })
public class SchedulerQueueListener implements MessageListener {
...
@Override
public void onMessage(Message message) {
   ...
   service = (IScheduledWorkerService) new InitialContext().lookup(jndiName);
   EJobResult eJobResult = service.executeJob(message);
   ...
}

样本工作者:

@Singleton
@LocalBinding(jndiBinding = SampleJobWorkerService.JNDI_NAME)
public class SampleJobWorkerService implements IScheduledWorkerService {

...
    @EJB(name = "SampleEJB/local")
    private ISampleEJB sampleEjb;
...
    @Override
    public EJobResult executeJob(Message message) {
    int state = sampleEjb.doSomething(message.getLongProperty(A_PROPERTY));
    }

在这种情况下,sampleEjb - 成员有时会为空

2 个答案:

答案 0 :(得分:1)

  1. 作为一种解决方法,您可以创建一个具有一定延迟的超时的计时器,而不是直接从MDB调用EJB。因此执行会有一些延迟。

    在Timer的超时方法中,你可以调用singleton EJB,以防万一调用其他非单例EJB。

  2. 特定于JBoss:可以在发送之前尝试在消息对象中设置属性。

    msg.setLongProperty("JMS_JBOSS_SCHEDULED_DELIVERY", (current + delay));

    其他替代方案是_JBM_SCHED_DELIVERY

  3. 修改:

    对于第一部分,您可以进行JTA事务,这可能跨越JMS和& EJB。故障转移&其他事情可能会相应处理。

    您还可以增加邮件对象的重新传递延迟。

    <address-setting match="jms.queue.someQueue">
            <redelivery-delay>5000</redelivery-delay>
    </address-setting>
    

答案 1 :(得分:0)

此刻我遇到了同样的麻烦。

我建议您在单例bean上使用EJB 3 startup bean annotation @Startup来调用Message侦听器上的startDelivery方法。