LINUX.ORG.RU

Вопрос по организации очередей на PHP.

 , очереди


0

2

Я сейчас в своих проектах использую костыльный самопал на PHP-MySQL. Потребности такие:

— PHP-скрип вызывает метод добавления задачи, передавая нужный к вызову класс. Опционально — метод, параметры, приоритет...

— Диспетчер следит, чтобы задание выполнилось:
—— Многопоточно, с изоляцией памяти (утечки и падения не должны сказываться на диспетчере и других потоках)
—— С минимальной задержкой (реально обеспечивается задержка ≈1/число воркеров секунд)
—— При падении воркера задача не снимается, а откладывается с таймаутом (т.е. воркер берёт из очереди задание, отмечая, что оно уже занято, чтобы другие воркеры не трогали, но снимает его из очереди только после успешного выполнения).

Велосипедить начал, когда полностью разочаровался в Gearman (нельзя снимать задачу из очереди только после успешной обработки, нельзя задавать приоритеты, сложно с отладочной целью следить за очередью, нельзя ставить отложенные задачи, да и вообще требует лишних сущностей в виде geamand и библиотек для работы с ним, в то время как под mysql обычно итак любая система развёрнута, а мой движок в общем случае позволяет с любой базой работать и т.п.)

После Gearman'а бегло знакомился с другими системами обработки очередей, но нужного функционала не видел. С другой стороны, системы эти всё сложнее, так что я мог при беглом просмотре просто не докопаться до глубин.

Посему и вопрос — может, потребное мне реализуется легко на чём-то общепопулярном, чтобы я мог переключиться на готовое решение и не тратить время на своё?

★★★★★

Не сталкивался, ни чего не подскажу.

Но вот это:

При падении воркера задача не снимается, а откладывается с таймаутом (т.е. воркер берёт из очереди задание, отмечая, что оно уже занято, чтобы другие воркеры не трогали, но снимает его из очереди только после успешного выполнения).

Ты или плохо описал или я тупой и не понял. Но. Воркер взял задачу, отметил ее, начал выполнять упал... и? Задача так и осталась отмеченной и ее больше никто не возьмет. Как ты детектишь падение воркера?

Suntechnic ★★★★★
()
Ответ на: комментарий от Suntechnic

Как ты детектишь падение воркера?

По таймауту задачи. Воркер, забирая задачу ставит таймстамп. Диспетчер через N минут (в принципе, можно передавать в параметрах задачи, но у меня сейчас фиксировано) считает, что воркер обломался и запускает нового. Поведение тоже, в принципе, можно настраиваться в параметрах задачи, например, убивать задачу через N попыток, но у меня сейчас крутится вечно, разбираю такие случаи вручную, соответственно, задача снимется, когда я исправлю ошибку.

В случае падения, конечно, речи об оперативном, за доли секунды, отклике не идёт, но это уже исключительная ситуация.

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от KRoN73

А. Тогда ясно. Я бы прикрутил еще апдейт таймстампа воркером если он продолжает ее выполнение, чтобы диспетчер видел когда он последний раз откликнулся и случайно не передал успешно выполняющуюся, но чуть притормозившую задачу.

Suntechnic ★★★★★
()
Ответ на: комментарий от Suntechnic

Я бы прикрутил еще апдейт таймстампа воркером если он продолжает ее выполнение

В принципе можно, но этим уже задача будет заниматься, типа, в глубоком цикле периодически вызывать $this->worker()->ping() (сам воркер в одном потоке с задачей, так что пока она работает «его нет»). Это, кстати, с одной стороны вводит лишнюю сущность, с другой, позволит диспетчеру быстро обнаружить упавшего воркера и усложнить процесс обработки — перезапускать задачу сразу же после первого падения и увеличивать ожидание при следующих.

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от zz

Супер простой воркфлоу, читаемый код, если нет фич - можно форкнуть и начать отсюда.

zz ★★★★
()
Ответ на: комментарий от zz

Ага, интересно. Логика близка к моей, только что под Redis, а не MySQL. Оценю, если будет годно на практике — попробую перейти.

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от KRoN73

только что под Redis, а не MySQL

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

Suntechnic ★★★★★
()
Ответ на: комментарий от Suntechnic

Ну так оно ж лучше для этого подходит

В плане производительности и лёгкости масштабирования — да. С точки зрения наличия на каждом левохосте — нет :)

KRoN73 ★★★★★
() автор топика

Была однажды похожая задача, тоже обошелся самопалом.
В описании твоего диспетчера не увидел требований к обеспечению контроля за количеством одновременно выполняющихся заданий. Необходимая в хозяйстве вещь ;)

tuxin
()
Ответ на: комментарий от tuxin

В описании твоего диспетчера не увидел требований к обеспечению контроля за количеством одновременно выполняющихся заданий

Оно равно числу воркеров, а число воркеров фиксировано :)

KRoN73 ★★★★★
() автор топика

Если не сложно, расскажите про схожие решения на java.

anonymous
()

в свое время тоже не нашел готового решения - слепил велосипед

EugeneBas ★★
()

Забавно) Прямо сейчас пилю велосипед аналогичный Вашему, только из-за взаимодействия с API у задач состояний побольше. Обязательно дайте знать, если найдёте годное решение.

konfuji
()
Ответ на: комментарий от konfuji

Чуть выше отвечал на Вопрос по организации очередей на PHP. (комментарий) — интересное решение, очень похожее на моё. Пока «работает — не трогай» мой вариант, но как дойдёт очередь дорабатывать, буду смотреть на практике, м.б. перейду на php-resque. Логика та же, так что менять почти ничего не придётся, а redis в качестве бэкенда интереснее, чем мой mysql.

KRoN73 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.