RabbitMQ: как правильно выполнять тяжелые задачи?

Всем привет!
У нас на проекте отправляются задания на генерацию отчетов в очередь rabbitmq.
Саму очередь обслуживает php-консюмер (работает через php-amqplib).

Проблема в том, что генерация отчетов, может занимать 10 мин, некоторые даже по часу..

Консюмер работает следующим образом:
берет N-сообщений из очереди, и начинает сразу же генерировать отчеты.

В момент, когда консюмер занят генераций отчета, как я понял, rabbitmq присылает некоторые проверки на жизнеспособность консюмера — heartbeat . По умолчанию, если консюмер не отвечает 60 сек., то при следующей итерации вылетает ошибка, что потеряно соединение.

У меня два вопроса:

1. Чем чревато отключение - heartbeat в rabbitmq ? Почитал тут но все равно не понял.
2. Как принято обрабатывать тяжелые задачи, которые получает косюмер ? может их не стоит сразу в самом консюмере запускать ? если запускать отдельным процессом, то возникает сразу вопрос, что делать, если в процессе генерации отчета произошла ошибка ? сообщение же из очереди прочитано и отправлено ack.

нужны best practices))
  • Вопрос задан
  • 1818 просмотров
Пригласить эксперта
Ответы на вопрос 6
samodum
@samodum
Какой вопрос - такой и ответ
Сам консюмер не должен обрабатывать задачи. Его основное назначение - разгрузить очередь и отправить задачи дальше, например в базу данных или на другие сервера через балансировщик. Лучше всего первый способ.
Далее некий воркер смотрит необработанные задачи в базе данных и неспеша их обрабатывает. Обработанные задачи помечает флагом.
Ответ написан
@yarkin
Была подобная проблема, сишный клиент в один поток не умел нормально в heartbeat. При отключении heartbeat'ов на уровне AMQP протокола были проблемы с "зависшими клиентами" на стороне RabbitMQ, когда приложение выходило непредвиденно. Настройка TCP keepalive помогла решить данную проблему.
Не знаю точно как работает современный php, но, если есть возможность держать отдельный поток для поддержания AMQP коннекта с включённым heartbeat'ом, то это будет лучше, чем через TCP keepalive. Отсылать ack обратно лучше всё же после завершения обработки задачи.
Ответ написан
Комментировать
@dmtrrr
Backend developer
Это выглядит как проблема библиотеки php-amqplib, php до сих пор не умеет в многопоточность?
Можно создавать процесс, который будет генерировать отчет.
Ответ написан
Комментировать
part_os
@part_os
Сложное в простом
А как вы поддерживаете соединение с БД, если в течении генерации отчёта нету запросов к ней? Мы делаем ping к БД, так же и к ребитту тем самым сообщая что косьюмер живой м работает.
Ответ написан
int128
@int128
developer
Частичное решение https://github.com/php-enqueue/enqueue-dev/blob/ma...
Ответ написан
Комментировать
Insolita
@Insolita
Отчаянная домохозяйка
php-amqplib тормозной, лучше расширение amqp из pecl
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы