Как временно отключить прослушиватель сообщений - PullRequest
15 голосов
/ 09 марта 2009

Каким будет хороший и хороший способ временно отключить прослушиватель сообщений? Проблема, которую я хочу решить:

  • Сообщение JMS получено слушателем сообщения
  • При попытке обработать сообщение появляется ошибка.
  • Я жду, пока моя система снова не будет готова обработать сообщение.
  • Пока моя система не готова, я не хочу больше сообщений, так что ...
  • ... Я хочу отключить прослушиватель сообщений.
  • Моя система снова готова к обработке.
  • Неудачное сообщение обрабатывается, а сообщение JMS подтверждается.
  • Снова включить прослушиватель сообщений.

Сейчас я использую Sun App Server. Я отключил прослушиватель сообщений, установив его в null в MessageConsumer, и снова включил его, используя setMessageListener (myOldMessageListener), но после этого я больше не получаю сообщений.

Ответы [ 7 ]

15 голосов
/ 10 марта 2009

Как насчет того, если вы не вернетесь из метода слушателя onMessage (), пока ваша система не будет готова снова обрабатывать сообщения? Это помешает JMS доставить другое сообщение этому потребителю.

Это асинхронный эквивалент не вызова метода receive () в синхронном случае.

Для данного сеанса JMS нет многопоточности, поэтому конвейер сообщений задерживается до возврата метода onMessage ().

Я не знаком с последствиями динамического вызова setMessageListener (). Javadoc говорит, что есть неопределенное поведение , если вызывается "когда сообщения используются существующим слушателем или получателем синхронизации". Если вы звоните изнутри onMessage (), похоже, вы попали в этот неопределенный регистр.

Есть методы start / stop на уровне Соединения, если это не слишком грубо для вас.

3 голосов
/ 09 марта 2009

Проблема решена с помощью обходного пути, заменив прослушиватель сообщения циклом receive (), но я по-прежнему заинтересован в том, как отключить прослушиватель сообщений и вскоре включить его снова.

0 голосов
/ 01 февраля 2018

Для временной остановки подключения входящих сообщений вам необходимо использовать метод stop() из интерфейса Connection: https://docs.oracle.com/javaee/7/api/javax/jms/Connection.html#stop--

Только не звоните connection.stop() из MessageListener, потому что согласно спецификации JMS. Вы получите тупик или исключение. Вместо этого вы можете вызвать connection.stop() из другого потока, вам просто нужно синхронизировать MessageListener и поток, который собирается приостановить соединение с функцией connection.stop()

0 голосов
/ 06 августа 2016

Я думаю, что вы можете позвонить

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--

Временно останавливает доставку входящих сообщений соединением. Доставка может быть возобновлена ​​с использованием метода начала подключения. Когда соединение прекращается, доставка всем потребителям сообщений соединения запрещается: синхронный блок приема и сообщения не доставляются получателям сообщений.

0 голосов
/ 14 июля 2009

В 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
0 голосов
/ 09 марта 2009

В WebLogic вы можете настроить максимальное количество повторов, очередь ошибок для обработки сообщений, которые превышают максимальный предел повторных попыток, и другие параметры. Я не уверен, что у меня в голове, но вы также можете указать период ожидания. Все это доступно вам в консоли администратора. Я бы посмотрел на администратора вашего провайдера JMS и выяснил, может ли он сделать что-то подобное.

0 голосов
/ 09 марта 2009

Мне кажется, что сообщения доставляются, но с ними ничего не происходит, потому что у вас нет подключенного слушателя. Прошло много времени с тех пор, как я что-то сделал с JMS, но разве вы не хотите, чтобы сообщение отправлялось в очередь недоставленных сообщений или что-то в то время, пока вы исправляете систему, а затем перемещаете сообщения обратно в исходную очередь, как только снова готовы к обработке?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...