Как приостановить подписчика темы JMS от получения сообщений

Моя установка: JBoss Messaging 1.4, работающий на JBoss 4.2.3

У меня есть пара MDB, которые подписываются на одну тему, и onMessage () MDB пытается доставить полученное сообщение каждой веб-службе.

Моя проблема в том, что я не могу понять, как приостановить подписку в случае, если веб-сервис отключен.

Мой план - сделать в onMessage () следующее:

  1. попытаться доставить в веб-службу
  2. если офлайн:
  3. -> приостановить подписку
  4. -> выбросить исключение в onMessage (), чтобы JMS повторно доставил сообщение, пока веб-служба снова не перейдет в онлайн
  5. -> начать подписку

Я хочу приостановить ТОЛЬКО ту подписку, в которой возникла проблема, - НЕ все мои подписчики.

Любые предложения о том, как это решить?


person Community    schedule 11.08.2009    source источник
comment
Спасибо за все советы! :-) В качестве временного решения я реализовал следующее: 1. если хост отключен, выбросить RuntimeException, чтобы вызвать откат 2. использовать огромное значение повторной доставки в моем MDB с помощью @ActivationConfigProperty (propertyName = DLQMaxResent, propertyValue = 151200 ). Это 4 секунды для моего MDB, чтобы понять хост в автономном режиме * 151200 = повторная доставка в течение 1 недели ... этого должно быть достаточно, я надеюсь :) Это не очень хорошее решение, но оно работает, и со значением по умолчанию 15 для числа одновременных сообщений мои пункты назначения не будут атакованы DoS :)   -  person    schedule 19.08.2009


Ответы (3)


Почему вы хотите приостановить подписку? Просто создайте исключение и засните, скажем, на 30 секунд. Исключение откатит транзакцию JMS и вернет сообщение в очередь.

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

[EDIT] Если у вас много слушателей для одной и той же темы (из соображений производительности), я предлагаю создать независимый процесс, который будет прослушивать сообщения «Web service down» и в этом случае отменять подписку на всех обычных слушателей.

Затем процесс должен дождаться, пока служба снова станет доступной, и повторно подписать слушателей.

person Aaron Digulla    schedule 11.08.2009
comment
Ваше предложение кажется хорошей идеей! Я сейчас пробовал, но у меня проблемы с этим: входящие сообщения обрабатываются параллельно. Это приводит к тому, что во сне появляется много сообщений. Кроме того, максимальное количество повторных доставок в какой-то момент достигнет предела и затем будет помещено в DLQ, даже если хост еще не подключился к сети. Поэтому было бы неплохо просто приостановить прием новых сообщений слушателем до тех пор, пока хост снова не будет в сети. Является ли лучшим решением программная настройка моих слушателей тем и обработка моих входящих сообщений таким образом? Тогда, я думаю, намного проще приостановить / остановить это ...? - person ; 12.08.2009
comment
Смотрите мои правки. Да, если у вас много слушателей, вам нужен способ остановить их всех. В этом случае лучшим вариантом будет управление подписками с дополнительным процессом. - person Aaron Digulla; 12.08.2009

Разве вы не можете остановить слушателя, который слушает любые входящие сообщения в теме?

Вот ссылка на документ Listener, и у него есть метод паузы. Вы можете следовать тому же подходу, и подробности можно найти в их раздаче. http://synapse.apache.org/apidocs/org/apache/synapse/transport/jms/JMSListener.html.

Еще один, чтобы показать вам, как остановить своего потребителя: http://livedocs.adobe.com/blazeds/1/javadoc/flex/messaging/services/messaging/adapters/JMSConsumer.html#stop()

Все они в основном одинаковы.

person paradisonoir    schedule 11.08.2009
comment
Было бы неплохо, но я не могу понять, как это сделать в моем MDB. Если я программно настрою прослушиватель темы, я думаю, это легко, но мое решение состоит из простых MDB с одним onMessage (). Любой совет, как остановить () от этого? - person ; 12.08.2009

Это очень похоже на сценарий в Как временно отключить сообщение слушатель

Единственная разница в том, что вы MDB, а не простой клиент Java. Не могли бы вы просто не возвращаться из onMessage (), пока ваш веб-сервис снова не заработает? Вам нужно будет настроить логику onMessage () так, чтобы она блокировалась или переходила в спящий режим. Сон - это техническое нарушение спецификации EJB, но в зависимости от того, что вы рассматриваете в качестве альтернативы, он может быть не хуже.

person John M    schedule 14.08.2009