Что ж, если вы работаете в Linux, вы можете использовать pcntl_fork
, чтобы отключить детей. Затем «мастер» наблюдает за детьми. Каждый ребенок выполняет свою задачу и затем существует в обычном режиме.
Лично в моих реализациях мне никогда не требовалась очередь сообщений. Я просто использовал массив в «мастере» с блокировками. Когда ребенок получает работу, он записывает файл блокировки с идентификатором работы. Затем мастер будет ждать, пока этот ребенок не выйдет. Если файл блокировки все еще существует после выхода дочернего элемента, то я знаю, что задача не была выполнена, и повторно запустите дочерний элемент с тем же заданием (после удаления файла блокировки). В зависимости от вашей ситуации вы можете реализовать очередь в простой таблице базы данных. Вставьте задания в таблицу и проверяйте таблицу в мастере каждые 30 или 60 секунд на наличие новых заданий. Затем удаляйте их из таблицы только после того, как дочерний элемент закончил (и дочерний элемент удалил файл блокировки). Это может иметь проблемы, если у вас одновременно работает несколько «master», но вы можете реализовать глобальный «master pid файл» для обнаружения и предотвращения нескольких экземпляров ...
И я бы не советовал разветвляться с FastCGI. Это может привести к некоторым очень неясным проблемам, поскольку среда должна сохраняться. Вместо этого используйте CGI, если у вас должен быть веб-интерфейс, но в идеале используйте приложение CLI (демон). Для взаимодействия с мастером из других процессов вы можете использовать сокеты для связи по протоколу TCP или создать файл FIFO для связи.
Что касается обнаружения зависших работников, вы могли бы реализовать систему «сердцебиения», при которой ребенок выдает SIG_USR1
ведущему процессу каждые столько секунд. Тогда, если вы не слышали от ребенка в два или три раза за это время, он может быть повешен. Но дело в том, что PHP не многопоточный, вы не можете сказать, завис ли ребенок или он просто ожидает блокирующий ресурс (например, вызов базы данных) ... Что касается реализации "сердцебиения" Вы можете использовать тиковую функцию , чтобы автоматизировать сердцебиение (но имейте в виду, что блокировка вызовов по-прежнему не будет выполняться) ...