Комментарии 10
вопрос от начинающего кроликовода:
какие есть вообще best practices по подтверждению сообщений, в случае если обработка сообщения сервисом длится относительно долго (например 10-15 минут)? подтвердить сразу, завести отдельную очередь для неуспешно обработанных сообщений? или слать акк только после успешной обработки?
например, публикуется сообщение в очередь для обработчика видео, сервис обработки видео читает сообщение, но для обработки нужно 10 минут. при базовой настройке у меня просто отваливается соединение.
видео бывают разные, обработка может занимать еще дольше
Rabbit разрывает соединение согласно настройке heartbeat, если между сервером и клиентом не ходят пакеты дольше чем 2*heartbeat. Можно:
отключить проверку подключения (heartbeat=0)
поставить heartbeat таким, чтобы не успевало разрываться подключение, пока работает ваш скрипт
периодически слать "ping" в сторону Rabbit, чтобы он считал, что клиент живой. Естественно, промежутки между отправками пакетов должны быть меньше 2*heartbeat
Стоит учесть, что можно выставить hearbeat как на сервере, так и на клиенте. При этом максимальное значение выбирается из серверной настройки. Т.е. если на сервере установлено 5 минут, а на клиенте выставили 10 минут, то heartbeat будет 5 минут
благодарю за ответ!
не совсем понял про пинг, достаточно просто слать get на адрес / порт раббита? или там какой-то особый пинг? беглый гугл результатов не дал
Я имею ввиду внутренний пинг, т.е. в открытый канал что-нибудь посылать. Например, в библиотеке для PHP есть метод write_heartbeat, где в канал шлется какой-то набор байт https://github.com/php-amqplib/php-amqplib/blob/master/PhpAmqpLib/Wire/IO/AbstractIO.php#L211
Думаю, в других языках есть аналог этого метода
Подтверждение сообщения зависит от бизнес-логики. Я предпочитаю следующий сценарий: при получении сообщения я фиксирую его, например, создавая запись в базе данных, затем подтверждаю получение сообщения и только после этого приступаю к его обработке.
Что касается удержания соединения, то в официальной документации RabbitMQ указано:
https://www.rabbitmq.com/docs/heartbeats
Здесь говорится, что на стороне сервера по умолчанию соединение разрывается через 60 секунд бездействия клиента. Это значение можно изменить как на сервере, так и на клиенте.
Если вы используете библиотеку pika для Python, обратите внимание на следующие ссылки:
Допустим я плохо читал документацию.
Вопрос нюба к эксперту - можно ли вернуть сообщение взад?
Не в конец очереди, а в голову. "Взял - не подошло - вернул на место".
PS. понятно, что это будет уже не очередь (queue), а дек (dequeue), но очень надо очень.
В этом плане ни RabbitMQ ни Kafka пока не удовлетворяет.
Да, можно. Методы nack или/и reject. Или самый тупой способ, не подтверждая получения (ack) закрыть канал или отключиться от rabbit
Насколько я помню:
- nack - это "не принять сообщение". Не запихнуть взад ,а именно не принять. А такое как принять и я потом передумал - не.
- reject запихивает сообщение в конец очереди.
Низачет.
У nack есть возможность requeue
https://www.rabbitmq.com/docs/nack
When a message is requeued, it will be placed to its original position in its queue, if possible. If not (due to concurrent deliveries and acknowledgements from other consumers when multiple consumers share a queue), the message will be requeued to a position closer to queue head.
Вы не правы. Оба метода отправляют сообщение в начало очереди. Отличие в том, что reject работает только для одного полученного сообщения, а nack может массово отклонять полученные сообщения. Если получаете и обрабатываете сообщения по одному, то разницы нет
Плюс у обоих методов есть флаг requeue - т.е. отправить сообщение назад в очередь или удалить
А такое как принять и я потом передумал - не
За это как раз отвечает флаг requeue
Брокеры сообщений на практике: как подключиться и пользоваться RabbitMQ в Python