暂时禁用消息监听器的好方法是什么?我想解决的问题是:
目前,我正在使用Sun App Server。我通过在MessageConsumer中将其设置为null来禁用消息侦听器,并使用setMessageListener(myOldMessageListener)再次启用它,但在此之后我不再收到任何消息。
答案 0 :(得分:15)
如果你没有从onMessage()监听器方法返回,直到系统准备好再次处理消息,那该怎么办?这将阻止JMS向该消费者传递另一条消息。
这是在同步情况下不调用receive()的异步等价物。
给定的JMS会话没有多线程,因此在onMessage()方法返回之前,会保留消息管道。
我不熟悉动态调用setMessageListener()的含义。如果在“现有侦听器或同步消费者正在使用消息时”调用javadoc,则表示there's undefined behavior。如果你是在onMessage()内部进行调用,那听起来就像是你遇到了那个未定义的情况。
答案 1 :(得分:3)
通过使用receive()循环替换消息侦听器的解决方法解决了问题,但我仍然对如何禁用消息侦听器并再次启用它感兴趣。
答案 2 :(得分:0)
在我看来,消息正在传递,但是没有任何事情发生在他们身上,因为你没有附加听众。已经有一段时间了,因为我已经对JMS做了任何事情,但是你不希望在修复系统时将消息发送到死信队列,或者在你修复系统后将消息移回原始队列准备再次处理?
答案 3 :(得分:0)
在WebLogic上,您可以设置最大重试次数,错误队列以处理超过最大重试次数限制的消息以及其他参数。我不确定我的头脑,但你也可以指定一个等待期。您可以在管理控制台中使用所有这些功能。我会看一下你所拥有的JMS提供者的管理员,看看它是否可以做类似的事情。
答案 4 :(得分: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
答案 5 :(得分: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--
暂时停止连接传入的消息。可以使用连接的启动方法重新开始传递。当连接停止时,禁止向所有连接的消息使用者传递:同步接收阻止,并且不将消息传递给消息监听器。
答案 6 :(得分:0)
要暂时停止连接传入的消息,您需要使用stop()
界面中的Connection
方法:https://docs.oracle.com/javaee/7/api/javax/jms/Connection.html#stop--
根据JMS规范,只是不要从connection.stop()
致电MessageListener
。你会遇到僵局或异常。相反,您可以从不同的线程调用connection.stop()
,您只需要同步MessageListener
和将暂停与函数connection.stop()
的连接的线程