如何暂时禁用消息侦听器

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

  • 消息侦听器接收JMS消息
  • 尝试处理邮件时出错。
  • 我等待我的系统再次准备好能够处理消息。
  • 在我的系统准备好之前,我不再需要任何消息了,所以…
  • …我想禁用消息监听器。
  • 我的系统已准备好再次处理。
  • 处理失败的消息,并确认JMS消息。
  • 再次启用消息侦听器。

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

如果你没有从onMessage()监听器方法返回,直到你的系统准备再次处理消息,那该怎么办? 这将阻止JMS向该消费者传递另一条消息。

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

对于给定的JMS会话,没有multithreading,因此在onMessage()方法返回之前,会保留消息管道。

我不熟悉动态调用setMessageListener()的含义。 javadoc表示如果在“现有侦听器或同步使用者正在使用消息时”调用,则会出现未定义的行为 。 如果你是从onMessage()中调用的话,那听起来就像是你遇到了那个未定义的情况。

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

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

在我看来,消息正在传递,但是没有任何事情发生在他们身上,因为你没有附加听众。 已经有一段时间了,因为我已经对JMS做了任何事情,但是你不希望在修复系统时将消息发送到死信队列,或者在你修复系统后将消息移回原始队列准备再次处理?

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

在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 

我想你可以打电话

 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–

暂时停止连接传入的消息。 可以使用连接的start方法重新开始传递。 当连接停止时,将禁止传递到所有连接的消息使用者:同步接收块,并且消息不会传递给消息侦听器。

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

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