Мне нужно запустить PHP-скрипт как процесс демона (ждать инструкций и делать вещи). Работа cron не сделает это для меня, потому что действия должны быть предприняты, как только прибудет инструкция. Я знаю, что PHP не самый лучший вариант для процессов-демонов из-за проблем с управлением памятью, но по разным причинам мне приходится использовать PHP в этом случае. Я наткнулся на инструмент от libslack под названием Daemon ( http://libslack.org/daemon ), который, кажется, помогает мне управлять процессами демона, но за последние 5 лет не было никаких обновлений, поэтому мне интересно, знаете ли вы какие-нибудь другие альтернативы, подходящие для моего случая. Любая информация будет по достоинству оценена.
154
Ответы:
Вы можете запустить свой php-скрипт из командной строки (т.е. bash), используя
nohup php myscript.php &
&
ставит ваш процесс в фоновом режиме.Изменить:
Да, есть некоторые недостатки, но невозможно контролировать? Это просто неправильно.
Простое
kill processid
остановит это. И это все еще лучшее и простое решение.источник
nohup
и он&
делает то же самое: отсоединяет запущенный процесс от текущего экземпляра оболочки. Зачем мне они оба? Могу ли я не просто сделатьphp myscript.php &
илиnohup myscript.php
?? Спасибоnohup php myscript.php > myscript.log &
Другой вариант - использовать Upstart . Первоначально он был разработан для Ubuntu (и поставляется с ним по умолчанию), но предназначен для всех дистрибутивов Linux.
Этот подход аналогичен Supervisord и daemontools в том, что он автоматически запускает демон при загрузке системы и запускается при завершении сценария.
Как настроить это:
Создайте новый файл скрипта в
/etc/init/myphpworker.conf
. Вот пример:Запуск и остановка вашего демона:
Проверьте, работает ли ваш демон:
Спасибо
Большое спасибо Кевину ван Зонневельду , где я изучил эту технику.
источник
sudo service myphpworker start/stop/status
работает только со службами, которые/etc/init.d
не находятся в службах upstart. @ matt-sich, похоже, раскрыл правильный синтаксис. Другой вариант - использовать Gearman или Resque, что позволяет выполнять фоновую обработку и деамонизацию.С новым systemd вы можете создать сервис.
Вы должны создать файл или символическую ссылку на
/etc/systemd/system/
, например. myphpdaemon.service и разместите контент, подобный этому, myphpdaemon будет названием службы:Вы сможете запускать, получать статус, перезапускать и останавливать сервисы, используя команду
systemctl <start|status|restart|stop|enable> myphpdaemon
PHP-скрипт должен иметь своего рода «цикл» для продолжения работы.
Рабочий пример:
Если ваша подпрограмма PHP должна выполняться один раз в цикле (например, дайджест), вы можете использовать сценарий оболочки или bash для вызова в служебный файл systemd вместо PHP напрямую, например:
Если вы выбрали эту опцию, вы должны изменить KillMode на
mixed
процессы, bash (main) и PHP (child) будут убиты.This method also is effective if you're facing a memory leak.
источник
systemctl status <your_service_name> -l
вывод, это даст вам подсказку, что происходит.Если вы можете - возьмите копию Advanced Programming в среде UNIX . Вся глава 13 посвящена программированию демонов. Примеры в C, но все необходимые функции имеют обертки в PHP (в основном расширения pcntl и posix ).
В двух словах - написание демона (это возможно только на ОС * nix - Windows использует сервисы) выглядит так:
umask(0)
чтобы предотвратить проблемы с разрешениями.fork()
и есть родительский выход.setsid()
.SIGHUP
(обычно это игнорируется или используется для подачи сигнала демону о необходимости перезагрузить его конфигурацию) иSIGTERM
(чтобы сообщить процессу о корректном завершении работы).fork()
снова и родительский выход.chdir()
.fclose()
stdin
,stdout
Иstderr
не пишите им. Правильный способ - перенаправить их в/dev/null
файл или в файл, но я не смог найти способ сделать это в PHP. Когда вы запускаете демон, возможно, перенаправить его с помощью оболочки (вам придется самому выяснить, как это сделать, я не знаю :).Кроме того, поскольку вы используете PHP, будьте осторожны с циклическими ссылками, поскольку сборщик мусора PHP, до PHP 5.3, не имел возможности собирать эти ссылки, и процесс будет иметь утечку памяти до тех пор, пока в конечном итоге не произойдет сбой.
источник
Я запускаю большое количество PHP-демонов.
Я согласен с вами, что PHP не лучший (или даже хороший) язык для этого, но демоны делятся кодом с веб-компонентами, поэтому в целом это хорошее решение для нас.
Мы используем daemontools для этого. Это умный, чистый и надежный. На самом деле мы используем его для запуска всех наших демонов.
Вы можете проверить это на http://cr.yp.to/daemontools.html .
РЕДАКТИРОВАТЬ: быстрый список функций.
источник
Ты можешь
nohup
как предложил Хенрик.screen
и запускайте вашу PHP-программу как обычный процесс. Это дает вам больше контроля, чем при использованииnohup
.Я бы порекомендовал самый простой метод (на мой взгляд, экран), а затем, если вам нужны дополнительные функции или функции, перейдите к более сложным методам.
источник
Существует несколько способов решения этой проблемы.
Я не знаю специфики, но, возможно, есть другой способ запустить процесс PHP. Например, если вам нужен код для запуска на основе событий в базе данных SQL, вы можете настроить триггер для выполнения вашего скрипта. Это действительно легко сделать в PostgreSQL: http://www.postgresql.org/docs/current/static/external-pl.html .
Честно говоря, я думаю, что вам лучше всего создать процесс Damon с использованием nohup. nohup позволяет продолжить выполнение команды даже после выхода пользователя из системы:
Однако существует очень серьезная проблема. Как вы сказали, менеджер памяти PHP является полной фигней, он был построен с учетом того, что сценарий выполняется только в течение нескольких секунд, а затем существует. Ваш PHP-скрипт начнет использовать гигабайты памяти только через несколько дней. Вы ДОЛЖНЫ ТАКЖЕ создать скрипт cron, который запускается каждые 12 или, может быть, 24 часа, который убивает и повторно запускает ваш php-скрипт следующим образом:
Но что, если сценарий был в середине работы? Ну, kill -3 - это прерывание, это то же самое, что делать Ctrl + C на CLI. Ваш php-скрипт может перехватить это прерывание и корректно завершить работу с помощью библиотеки PHP pcntl: http://php.oregonstate.edu/manual/en/function.pcntl-signal.php
Вот пример:
Идея, стоящая за $ lock, заключается в том, что PHP-скрипт может открыть файл с помощью fopen ("file", "w") ;. Только один процесс может иметь блокировку записи в файл, поэтому, используя это, вы можете убедиться, что запущена только одна копия вашего PHP-скрипта.
Удачи!
источник
Кевин ван Зонневельд написал очень хорошую подробную статью по этому вопросу , в своем примере он использует
System_Daemon
пакет PEAR (последняя дата выпуска 2009-09-02).источник
Проверьте https://github.com/shaneharter/PHP-Daemon
Это объектно-ориентированная библиотека демонов. Он имеет встроенную поддержку таких вещей, как ведение журнала и устранение ошибок, а также поддержку создания фоновых рабочих.
источник
Недавно у меня возникла потребность в кроссплатформенном решении (Windows, Mac и Linux) для проблемы запуска PHP-скриптов в качестве демонов. Я решил эту проблему, написав собственное решение на C ++ и создав двоичные файлы:
https://github.com/cubiclesoft/service-manager/
Полная поддержка Linux (через sysvinit), а также запуск служб Windows NT и Mac OSX.
Если вам просто нужен Linux, то пара других решений, представленных здесь, работают достаточно хорошо и, в зависимости от вкуса. В наши дни также есть Upstart и systemd, у которых есть запасные варианты для сценариев sysvinit. Но половина смысла использования PHP в том, что он кроссплатформенный по своей природе, поэтому код, написанный на языке, имеет довольно хорошие шансы работать везде, как есть. Недостатки начинают проявляться, когда в картину входят определенные внешние нативные аспекты уровня ОС, такие как системные службы, но эта проблема возникает с большинством языков сценариев.
Попытка поймать сигналы, как кто-то здесь предложил в PHP пользователя, не очень хорошая идея.
pcntl_signal()
Внимательно прочитайте документацию, и вы быстро узнаете, что PHP обрабатывает сигналы, используя некоторые довольно неприятные методы (в частности, «тики»), которые сжимают кучу циклов для чего-то, что редко замечается процессами (то есть сигналами). Обработка сигналов в PHP также едва доступна на платформах POSIX, и поддержка отличается в зависимости от версии PHP. Изначально это звучит как приличное решение, но оно не очень полезно.С течением времени PHP также становился лучше в вопросах утечки памяти. Вы все еще должны быть осторожны (синтаксический анализатор DOM XML имеет тенденцию к утечке), но я редко вижу сбежавшие процессы в наши дни, а средство отслеживания ошибок PHP довольно тихо по сравнению с прошлыми днями.
источник
Как уже упоминали другие, запустить PHP как демон довольно легко, и это можно сделать с помощью одной строки команды. Но настоящая проблема заключается в том, чтобы поддерживать его в рабочем состоянии и управлять им. У меня была такая же проблема довольно давно, и хотя уже есть множество доступных решений, большинство из них имеют много зависимостей или сложны в использовании и не подходят для базовых целей. Я написал сценарий оболочки, который может управлять любым процессом / приложением, включая сценарии PHP Cli. Он может быть установлен как cronjob для запуска приложения и будет содержать приложение и управлять им. Если он выполняется снова, например, через тот же cronjob, он проверяет, запущено ли приложение или нет, если он это делает, то просто завершает работу и позволяет своему предыдущему экземпляру продолжать управлять приложением.
Я загрузил его на github, не стесняйтесь использовать его: https://github.com/sinasalek/EasyDeamonizer
EasyDeamonizer
Просто следит за вашим приложением (запуск, перезапуск, журнал, монитор и т. Д.). универсальный скрипт для проверки правильности работы приложения. Преднамеренно он использует имя процесса instread файла pid / lock, чтобы предотвратить все его побочные эффекты и сделать скрипт как можно более простым и максимально быстрым, поэтому он всегда работает, даже когда перезапускается сам EasyDaemonizer. Характеристики
источник
Расширение Emil Ivaov ответ, Вы можете сделать следующее близко STDIN, STDOUT И STDERROR в PHP
По сути, вы закрываете стандартные потоки, так что PHP некуда писать. Следующие
fopen
вызовы установят стандартный IO в/dev/null
.Я прочитал это из книги Роба Алея - PHP вне Интернета
источник
Я написал и развернул простой php-демон, код здесь
https://github.com/jmullee/PhpUnixDaemon
Особенности: удаление привилегий, обработка сигналов, регистрация
Я использовал его в обработчике очереди (сценарий использования: вызвать длительную операцию с веб-страницы, не заставляя генерирующий страницу php ждать, т.е. запустить асинхронную операцию) https://github.com/jmullee/PhpIPCMessageQueue
источник
Вы можете проверить PM2 здесь, http://pm2.keymetrics.io/
создайте ssh-файл, такой как worker.sh, вставьте в свой php-скрипт, с которым вы будете иметь дело.
worker.sh
начало демона
Ура, вот и все.
источник