Как бороться с состоянием гонки в очереди laravel с множественными воркерами?

Есть Job, который принимает в хендлер Eloquent-модель и делает какую-то полезную работу.
После завершения job'а модель удаляется.

Есть supervisorctl, который запускает четыре процесса-воркера (artisan queue:work), все они обрабатывают одну очередь.

Проблема: воркеры находятся в состоянии гонки и берут на выполенение один и тот же job. На это указывают ошибки в логе о том, что модель переданная в хендлер не существует.

Пробовал с драйверами БД и Redis проблема одна. Если юзать db-драйвер, то в лог падают еще и mysql-дедлоки, что собственно тоже свидетельствует от том, что два воркера взяли один и тот же job.

Какого хрена?)))

Погуглил — полно народа жалуются и никто решить не может.
Единственное решение-костыль — это для каждого воркера сделать свою очередь, а в своем коде реализовать какой-то балансировщик для раcпределения однотипных задач в разные очереди. Что-то типа ->onQueue('my_queue_name'.rand(1,4))

Неужели нет нормального солюшна?
  • Вопрос задан
  • 1952 просмотра
Пригласить эксперта
Ответы на вопрос 2
tumbler
@tumbler
бекенд-разработчик на python
Если artisan queue:work такой костыльный, что берет из очереди (из очереди!!! это ж его основное предназначение!) одну и ту же задачу, то может выкинуть его нафиг как профессионально непригодный?
Если нельзя выкинуть, то можно навесить лок на уровне редиса - блокировать Job при начале обрабокти и отпускать по завершении. https://redis.io/topics/distlock
Ответ написан
Комментировать
lazychaser
@lazychaser
Использую отличное решение от одного товарища. Он использует оптимистичное блокирование, https://github.com/ph4r05/laravel-queue-database-ph4
Проверено на нескольких проектах
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы