У нас есть слушатель Java, который считывает текстовые сообщения из очереди в JBossMQ. Если нам нужно перезагрузить JBoss, слушатель не будет снова подключаться и снова начнет читать сообщения. Мы просто получаем сообщения в файле журнала слушателя каждые 2 минуты, говоря, что он не может подключиться. Есть ли что-то, что мы не устанавливаем в нашем коде или в JBossMQ? Я новичок в JMS, поэтому любая помощь будет принята с благодарностью. Спасибо.
Повторное подключение JMS-слушателя к JBossMQ
Ответ 1
Вы должны реализовать в своем клиентском коде javax.jms.ExceptionListener. Вам понадобится метод, называемыйException. Когда соединение клиента теряется, вы должны получить исключение JMSException, и этот метод будет вызван автоматически. Единственное, на что вам нужно обратить внимание, это то, что вы намеренно отключились от JBossMQ - это также вызовет исключение.
Некоторый код может выглядеть так:
public void onException (JMSException jsme)
{
if (!closeRequested)
{
this.disconnect();
this.establishConnection(connectionProps, queueName, uname, pword, clientID, messageSelector);
}
else
{
//Client requested close so do not try to reconnect
}
}
В вашем коде "connectionConnection" вы затем реализуете конструкцию while(!initialized)
, содержащую try/catch внутри нее. Пока вы не убедитесь, что вы правильно подключились и подписались, оставайтесь внутри цикла while, захватывая все JMS/Naming/etc. исключения.
Мы использовали этот метод в течение многих лет с JBossMQ, и он отлично работает. У нас никогда не возникало проблем с нашими JMS-клиентами, которые не повторно подключались после подпрыгивания JBossMQ или потеряли наше сетевое подключение.
Ответ 2
Я настоятельно рекомендую вам использовать абстракции Spring для JMS, такие как MessageListenerContainer, чтобы иметь дело с повторным подключением, транзакциями и пулом для вас, Вам просто нужно предоставить MessageListener и настроить MessageListenerContainer с ConnectionFactory, а контейнер сделает все остальное.
Ответ 3
Если вы являетесь чисто слушателем и не выполняете никаких других вызовов JMS, отличных от настройки соединения, то ответ "onException()" корректен.
Если вы выполняете какие-либо вызовы JMS в вашем коде, просто использовать метод onException() недостаточно. Проблемы передаются от поставщика JMS в приложение либо через исключение по вызову метода JMS, либо через обратный вызов onException(). Не оба.
Поэтому, если вы вызываете какие-либо JMS-методы из вашего кода, вы также захотите вызвать эту логику пересоединения, если вы получите какие-либо исключения из этих вызовов.
Ответ 4
Часть совета из личного опыта. Переход на JBoss Messaging. Я видел его в производстве в течение 4 месяцев без проблем. Он обладает полностью прозрачным отказоустойчивостью - среди многих других функций.
Кроме того, если вы переходите к Spring, будьте очень осторожно с JmsTemplate.