18

什么是暂时禁用消息侦听器的好方法?我要解决的问题是:

  • 消息侦听器接收到 JMS 消息
  • 尝试处理消息时出现错误。
  • 我等待我的系统再次准备好能够处理消息。
  • 在我的系统准备好之前,我不想再收到任何消息,所以...
  • ...我想禁用消息侦听器。
  • 我的系统已准备好再次处理。
  • 失败的消息得到处理,JMS 消息得到确认。
  • 再次启用消息侦听器。

现在,我正在使用 Sun App Server。我通过在 MessageConsumer 中将其设置为 null 来禁用消息侦听器,并使用 setMessageListener(myOldMessageListener) 再次启用它,但在此之后我不再收到任何消息。

4

7 回答 7

15

onMessage()如果您在系统准备好再次处理消息之前不从侦听器方法返回,该怎么办?这将阻止 JMS 向该消费者传递另一条消息。

receive()这是在同步情况下不调用的异步等价物。

给定的 JMS 会话没有多线程,因此消息管道一直保持到onMessage()方法返回。

我不熟悉动态调用的含义setMessageListener()。javadoc 说,如果在“现有侦听器或同步消费者正在使用消息时”调用,则会出现未定义的行为。如果您从 inside 调用onMessage(),听起来您遇到了未定义的情况。

连接级别有启动/停止方法,如果这对您来说不是太粗粒度的话。

于 2009-03-09T22:49:38.563 回答
5

通过用 receive() 循环替换消息侦听器的解决方法解决了问题,但我仍然对如何禁用消息侦听器并很快再次启用它感兴趣。

于 2009-03-09T20:39:02.993 回答
0

在我看来,消息正在传递,但它们没有发生任何事情,因为您没有附加侦听器。自从我用 JMS 做任何事情以来已经有一段时间了,但是您不希望在修复系统时将消息发送到死信队列或其他东西,然后在您完成后将消息移回原始队列准备好再次处理了吗?

于 2009-03-09T11:56:06.247 回答
0

在 WebLogic 上,您可以设置最大重试次数、用于处理超过最大重试限制的消息的错误队列以及其他参数。我不确定我的头,但你也可以指定一个等待期。所有这些都可以在管理控制台中使用。我会查看您拥有的 JMS 提供程序的管理员,看看它是否可以做类似的事情。

于 2009-03-09T13:11:30.120 回答
0

在 JBoss 中,以下代码可以解决问题:

   MBeanServer mbeanServer = MBeanServerLocator.locateJBoss();
    ObjectName objName = new ObjectName("jboss.j2ee:ear=MessageGateway.ear,jar=MessageGateway-EJB.jar,name=MessageSenderMDB,service=EJB3");
    JMSContainerInvokerMBean invoker = (JMSContainerInvokerMBean) MBeanProxy.get(JMSContainerInvokerMBean.class, objName, mbeanServer);

    invoker.stop(); //Stop MDB
    invoker.start(); //Start MDB
于 2009-07-14T18:01:52.113 回答
0

我想你可以打电话

messageConsumer.setMessageListener(null);

在 MessageListener 实现中并安排重建任务(例如在 ScheduledExecutorService 中)。这个任务应该调用

connection.stop();
messageConsumer.setMessageListener(YOUR_NEW_LISTENER);
connection.start();

它会起作用的。start() 和 stop() 方法用于重新启动传递结构(不是 TCP 连接)。

阅读 Javadoc https://docs.oracle.com/javaee/7/api/javax/jms/Connection.html#stop--

暂时停止连接传递传入消息。可以使用连接的启动方法重新启动交付。当连接停止时,将禁止向所有连接的消息消费者传递:同步接收阻塞,并且消息不会传递给消息侦听器。

于 2016-08-06T09:37:33.667 回答
0

要暂时停止连接传递传入消息,您需要使用接口中的stop()方法: https ://docs.oracle.com/javaee/7/api/javax/jms/Connection.html#stop--Connection

只是不要调用connection.stop()MessageListener因为根据 JMS 规范。你会遇到死锁或异常。相反,您可以connection.stop()从不同的线程调用,您只需要同步MessageListener和线程将挂起与函数的连接connection.stop()

于 2018-02-01T14:07:12.113 回答