Как клиент RabbitMQ может определить, когда он теряет соединение с сервером?
Если я подключен к RabbitMQ и прослушиваю события с помощью EventingBasicConsumer, как я могу сказать, был ли я отключен от сервера?
Я знаю, что есть событие выключения, но он не срабатывает, если я отключу сетевой кабель для имитации сбоя.
Я также пробовал событие ModelShutdown и CallbackException на модели, но, похоже, никто не работает.
изменить----- Тот, который я отметил как правильный ответ, но это была только часть решение для меня. Существует также функциональность сердцебиения, встроенная в RabbitMQ. Сервера указывается в файле конфигурации. По умолчанию это 10 минут, но конечно вы можете изменить это.
клиент также может запросить другой интервал для пульса, установив значение RequestedHeartbeat в экземпляре ConnectionFactory.
2 ответов
Я предполагаю, что вы используете библиотеки C#? (но даже так я думаю, что у других есть подобное событие).
вы можете сделать следующее:
public class MyRabbitConsumer
{
private IConnection connection;
public void Connect()
{
connection = CreateAndOpenConnection();
connection.ConnectionShutdown += connection_ConnectionShutdown;
}
public IConnection CreateAndOpenConnection() { ... }
private void connection_ConnectionShutdown(IConnection connection, ShutdownEventArgs reason)
{
}
}
Это пример, но отмечен ответ, что привело меня к этому.
var factory = new ConnectionFactory
{
HostName = "MY_HOST_NAME",
UserName = "USERNAME",
Password = "PASSWORD",
RequestedHeartbeat = 30
};
using (var connection = factory.CreateConnection())
{
connection.ConnectionShutdown += (o, e) =>
{
//handle disconnect
};
using (var model = connection.CreateModel())
{
model.ExchangeDeclare(EXCHANGE_NAME, "topic");
var queueName = model.QueueDeclare();
model.QueueBind(queueName, EXCHANGE_NAME, "#");
var consumer = new QueueingBasicConsumer(model);
model.BasicConsume(queueName, true, consumer);
while (!stop)
{
BasicDeliverEventArgs args;
consumer.Queue.Dequeue(5000, out args);
if (stop) return;
if (args == null) continue;
if (args.Body.Length == 0) continue;
Task.Factory.StartNew(() =>
{
//Do work here on different thread then this one
}, TaskCreationOptions.PreferFairness);
}
}
}
несколько вещей, чтобы отметить об этом.
Я использую для этой темы. Это захватывает все. Обычно вы хотите ограничить тему.
Я устанавливаю переменную под названием "stop", чтобы определить, когда процесс должен закончиться. Вы заметите, что цикл работает вечно, пока эта переменная не будет истинной.
Dequeue ждет 5 секунд, а затем уходит без получения данных, если есть нет новых сообщений. Это необходимо для того, чтобы мы прослушивали эту переменную stop и фактически выходили в какой-то момент. Измените значение по своему вкусу.
когда приходит сообщение, Я создаю код обработки в новом потоке. Текущий поток зарезервирован только для прослушивания сообщений rabbitmq, и если обработчик слишком долго обрабатывает, я не хочу, чтобы он замедлял другие сообщения. Вам может понадобиться или не понадобиться это в зависимости от вашей реализации. Однако будьте осторожны при написании кода обрабатывать сообщения. Если это займет минуту, чтобы запустить и получать сообщения в субсекунду раз вы будете работать из памяти или, по крайней мере, в серьезных проблемах производительности.