Используя RabbitMQ (Java-клиент), есть ли способ определить, закрыто ли сетевое соединение во время потребления? - PullRequest
13 голосов
/ 18 марта 2010

Я использую RabbitMQ на RHEL 5.3 с помощью клиента Java. У меня 2 узла (машины). Node1 использует сообщения из очереди на Node2, используя вспомогательный класс Java QueueingConsumer.

QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume("MyQueueOnNode2", noAck, consumer);
while (true)
{
   QueueingConsumer.Delivery delivery = consumer.nextDelivery();
   ... Process message - delivery.getBody()
}

Если интерфейс отключен на Node1 или Node2 (например, ifconfig eth1 down), клиент (см. Выше) никогда не узнает, что сети больше нет. Предоставляет ли RabbitMQ какой-либо тип конфигурации на клиенте Java, который можно использовать для определения, разорвалось ли соединение. Завершение работы сервера RabbitMQ на Node2 вызовет исключение ShutdownSignalException, которое может быть перехвачено, и приложение может войти в цикл повторного подключения. Но отключение интерфейса не приводит к возникновению каких-либо исключений, поэтому код будет ждать вечно на consumer.nextDelivery ().

Я также пытался использовать версию этого вызова по тайм-ауту. например,

QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume("MyQueueOnNode2", noAck, consumer);
int timeout_ms = 30000;
while (true)
{
   QueueingConsumer.Delivery delivery = consumer.nextDelivery(timeout_ms);
   if (delivery == null)
   {
      if (channel.isOpen() == false)             // Seems to always return true
      { throw new ShutdownSignalException(); }
   }
   else
   {
     ... Process message - delivery.getBody()
   }
}

но похоже, что это всегда возвращает true (даже если интерфейс не работает). Я предполагаю, что регистрация для ShutdownListener в соединении даст те же результаты, но еще не пробовал.

Есть ли способ настроить какое-то сердцебиение, или вам просто нужно написать собственную логику аренды (например, «Я здесь сейчас»), чтобы заставить это работать?

Ответы [ 2 ]

4 голосов
/ 19 марта 2010

В общем, вам гораздо лучше размещать вопросы о rabbitmq в списке рассылки rabbitmq-обсудить. Мы не склонны отслеживать вопросы, задаваемые за пределами этого.

Существует пульс, который вы можете настроить, хотя он по умолчанию выключен. Вы также можете включить TCP Keep Alive. Либо вызовите setRequestedHeartbeat на ConnectionFactory перед созданием нового соединения, либо подкласс ConnectionFactory переопределите метод configureSocket и вызовите socket.setKeepAlive(true). Оба должны привести к тому, что соединение заметит, когда сеть умрет.

3 голосов
/ 04 апреля 2010

Относительно метода isOpen, который хорошо описан в документации: http://www.rabbitmq.com/api-guide.html#shutdown-atomicity

Относительно выключения: при выключении узла 1 или 2 вы имеете в виду правильное приложение, а не сам сервер RabbitMQ? Зачем вам знать в любом приложении, если другое приложение отключается от посредника сообщений? Это не точка обмена сообщениями.

Единственное, что вы можете сделать, это отправлять сообщения с обязательным параметром. Это говорит серверу RabbitMQ, что вы ожидаете как минимум 1 прослушиватель для отправленного вами сообщения (будь то прямая очередь или какая-то очередь в обмене темами / разветвлениями). Если сообщение не может быть доставлено в какую-либо очередь, оно вернется на ваш канал и будет переадресовано данному ReturnListener.

...