асинхронная обработка с PHP – один рабочий на работу

Рассмотрим веб-приложение PHP, целью которого является принятие пользовательских запросов для запуска родовых асинхронных заданий, а затем создание рабочего процесса / потока для запуска задания. Рабочие места не особенно интенсивные для CPU или памяти, но, как ожидается, они будут блокировать вызовы ввода-вывода довольно часто. Не более одного или двух заданий должно запускаться в секунду, но из-за длительного времени работы может быть много заданий одновременно.

Поэтому крайне важно, чтобы задания выполнялись параллельно. Кроме того, каждая работа должна контролироваться демонами-менеджерами, ответственными за убийство повесных работников, прерывание работы по запросу пользователя и т. Д.

Каков наилучший способ реализовать такую ​​систему? Я вижу:

  1. Свертывание рабочего от менеджера – это, по-видимому, самый низкий уровень, и мне пришлось бы реализовать систему мониторинга самостоятельно. Apache – это веб-сервер, поэтому представляется, что для этого параметра требуется, чтобы любые PHP-рабочие запускались через FastCGI.
  2. Используйте какую-то очередь заданий / сообщений. (gearman, beanstalkd, RabbitMQ и т. д.). Первоначально это казалось очевидным выбором. После некоторых исследований я несколько запутался со всеми вариантами. Например, Gearman выглядит так, как будто он предназначен для огромных распределенных систем, где есть постоянный пул работников … поэтому я не знаю, правильно ли это для того, что мне нужно (один рабочий на работу).

Solutions Collecting From Web of "асинхронная обработка с PHP – один рабочий на работу"

Ну, если вы работаете в Linux, вы можете использовать pcntl_fork для pcntl_fork . Затем «мастер» наблюдает за детьми. Каждый ребенок выполняет свою задачу, а затем существует нормально.

Лично в моих реализациях мне никогда не нужна очередь сообщений. Я просто использовал массив в «master» с замками. Когда ребенок получает задание, он записывает файл блокировки с номером идентификатора задания. Затем мастер будет ждать, пока этот ребенок не выйдет. Если файл блокировки все еще существует после выхода дочернего элемента, то я знаю, что задача не была завершена, и перезапустите дочерний объект с тем же заданием (после удаления файла блокировки). В зависимости от вашей ситуации вы можете реализовать очередь в простой таблице базы данных. Вставьте задания в таблицу и проверьте таблицу в главном каждые 30 или 60 секунд для новых заданий. Затем удалите их из таблицы только после завершения дочернего процесса (и ребенок удалит файл блокировки). У этого были бы проблемы, если бы у вас было несколько «мастеров», работающих одновременно, но вы могли бы реализовать глобальный «главный файл pid» для обнаружения и предотвращения нескольких экземпляров …

И я бы не предложил разветвить FastCGI. Это может привести к некоторым очень неясным проблемам, поскольку среда должна сохраняться. Вместо этого используйте CGI, если у вас должен быть веб-интерфейс, но в идеале используйте приложение CLI (deamon). Чтобы взаимодействовать с мастером из других процессов, вы можете использовать сокеты для связи по протоколу TCP или создать файл FIFO для связи.

Что касается обнаружения повесившихся работников, вы можете реализовать систему «сердцебиение», когда ребенок выдает SIG_USR1 на главный процесс каждые столько секунд. Тогда, если вы не слышали от ребенка в два или три раза, это может быть повешено. Но дело в том, что PHP не многопоточен, вы не можете определить, висел ли ребенок или он просто ждет на блокирующем ресурсе (например, вызов базы данных) … Что касается реализации «сердечного ритма», , вы можете использовать функцию галочки для автоматизации сердечного ритма (но имейте в виду, что блокировка вызовов еще не выполняется) …

Рабочий рабочий может быть интересным:

https://github.com/qxsch/WorkerPool

https://github.com/qxsch/WorkerPool/blob/master/examples/asyncExample.php

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