Используя RabbitMQ (Java-клиент), есть ли способ определить, закрыто ли сетевое соединение во время потребления?
Я использую 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()
}
}
но кажется, что это всегда возвращает истину (даже если интерфейс не работает). Я предполагаю, что регистрация для ShutdownListener в соединении даст те же результаты, но еще не пробовал.
Есть ли способ настроить какое-то сердцебиение, или вам просто нужно написать собственную логику аренды (например, "Я здесь сейчас"), чтобы заставить это работать?
2 ответа
В общем, вам лучше размещать вопросы о rabbitmq в списке рассылки rabbitmq-обсудить. Мы не склонны отслеживать вопросы, задаваемые за пределами этого.
Существует пульс, который вы можете настроить, хотя по умолчанию он отключен. Вы также можете включить TCP Keep Alive. Либо позвони setRequestedHeartbeat
на ConnectionFactory
перед созданием нового соединения или подкласса ConnectionFactory
переопределить configureSocket
метод и вызов socket.setKeepAlive(true)
, Оба должны приводить к тому, что соединение замечает, когда сеть умирает.
Что касается метода isOpen, он хорошо описан в документации: http://www.rabbitmq.com/api-guide.html
Что касается выключения: при выключении узла 1 или 2 вы имеете в виду правильное приложение, а не сам сервер RabbitMQ? Зачем вам знать в любом приложении, если другое приложение отключается от посредника сообщений? Это не точка обмена сообщениями.
Единственное, что вы можете сделать, это отправлять сообщения с обязательным параметром. Это говорит серверу RabbitMQ, что вы ожидаете как минимум 1 прослушиватель для отправленного вами сообщения (будь то прямая очередь или какая-то очередь в обмене темами или разветвлениями). Если сообщение не может быть доставлено в какую-либо очередь, оно вернется на ваш канал и будет перенаправлено данному ReturnListener.