Как php файл сделать демоном

Обновлено: 04.07.2024

вы можете запустить свой PHP-скрипт из командной строки (т. е. bash), используя

nohup php myscript.php &

на & ставит свой процесс в фоновом режиме.

Edit:
Да, есть некоторые недостатки, но их невозможно контролировать? Это неправильно.
Простой kill processid остановит его. И это все еще лучшее и самое простое решение.

другой вариант-использовать выскочка. Изначально он был разработан для Ubuntu (и поставляется в комплекте по умолчанию), но предназначен для всех дистрибутивов Linux.

этот подход похож на Supervisord и сайтов, в том, что он автоматически запускает демон при загрузке системы и возрождается по завершении сценария.

как настроить его:

создать новый файл скрипта /etc/init/myphpworker.conf . Вот пример:

начинать & останавливать свой демон:

проверьте, работает ли ваш демон:

спасибо

большое спасибо Кевин ван Зонневельд, где я научился этой технике.

если вы можете - возьмите копию расширенное программирование в среде UNIX. Вся Глава 13 посвящена демоническому программированию. Примеры находятся в C, но все функции, которые вам нужны, имеют обертки в PHP (в основном pcntl и в POSIX расширения).

в нескольких словах-написание демона (это возможно только на основе * nix OS-es-Windows использует службы) выглядит так:

кроме того, поскольку вы используете PHP, будьте осторожны с циклическим ссылки, так как сборщик мусора PHP, до PHP 5.3, не имеет возможности собирать эти ссылки, и процесс будет утечка памяти, пока он в конечном итоге не аварийно завершит работу.

новые systemd в вы можете создать службу (на основе rhel linux).

вы должны создать файл или ссылка на /etc/systemd/system/ , например. мифпдемон.сервис и разместить такой контент, как этот, myphpdaemon будет имя сервиса:

вы сможете запустить, получить статус, перезапустить и остановить службы с помощью команды

systemctl <start|status|restart|stop|enable> myphpdaemon

скрипт PHP должен иметь своего рода "цикл" для продолжайте бежать.

если ваш PHP должен выполняться один раз в цикле (например, diggest), вы можете использовать сценарий оболочки или bash для вызова в файл службы systemd вместо PHP напрямую, например:

если вы выбрали эту опцию, вы должны изменить KillMode to mixed для процессов, bash(main) и php(child) будут убиты.

Примечание: каждый раз чтобы вы изменили свой "myphpdaemon"."вы должны запустите "systemctl daemon-reload", но не волнуйтесь, если вы этого не сделаете, это будет запрашивается при необходимости.

Я запускаю большое количество демонов PHP.

Я согласен с вами, что PHP не лучший (или даже хороший) язык для этого, но демоны делятся кодом с веб-компонентами, поэтому в целом это хорошее решение для нас.

для этого мы используем daemontools. Он умный, чистый и надежный. Фактически, мы используем его для управления всеми нашими демонами.

ИЗМЕНИТЬ: A краткий список функций.

  • автоматически запускает демона при перезагрузке
  • автоматический перезапуск dameon при сбое
  • ведение журнала обрабатывается для вас, включая опрокидывание и обрезку
  • интерфейс управления: 'svc ' и'svstat'
  • Unix дружественный (не плюс для всех, возможно)

Я бы рекомендовал самый простой метод (экран, на мой взгляд), а затем, если вы хотите больше функций или функций, перейдите к более сложным методам.

Существует несколько способов решения этой проблемы.

честно говоря, я думаю, что ваш лучший выбор-создать процесс Деймона использование nohup. nohup позволяет команде продолжать выполнение даже после выхода пользователя из системы:

существует, однако, очень серьезная проблема. Как вы сказали, менеджер памяти PHP-это полный мусор, он был построен с предположением, что скрипт выполняется всего несколько секунд, а затем существует. Ваш PHP скрипт начнет использовать гигабайты памяти всего через несколько дней. Вы также должны создать сценарий cron, который запускается каждые 12 или 24 часа, который убивает и повторно порождает ваш PHP-скрипт следующим образом:

идея $lock заключается в том, что php-скрипт может открыть файл с помощью fopen ("file","w");. Только один процесс может иметь блокировку записи в файле, поэтому с помощью этого вы можете убедиться, что работает только одна копия вашего PHP-скрипта.

Кевин ван Зонневельд написал очень хорошую подробную статью об этом в своем примере он использует System_Daemon груша пакет (дата последнего выпуска 2009-09-02).

это объектно-ориентированная библиотека демона. Он имеет встроенную поддержку для таких вещей, как ведение журнала и восстановление ошибок, и он поддерживает создание фоновых работников.

недавно мне понадобилось кросс-платформенное решение (Windows, Mac и Linux) для проблемы запуска PHP-скриптов в качестве демонов. Я решил проблему, написав собственное решение на основе C++ и создав двоичные файлы:

полная поддержка Linux (через sysvinit), а также служб Windows NT и Mac OSX launchd.

Если вам просто нужен Linux, то несколько других решений, представленных здесь работать достаточно хорошо и, в зависимости от вкуса. В наши дни также есть Upstart и systemd, которые имеют резервные копии сценариев sysvinit. Но половина смысла использования PHP заключается в том, что он кросс-платформенный по своей природе, поэтому код, написанный на этом языке, имеет довольно хорошие шансы работать везде как есть. Недостатки начинают проявляться, когда некоторые внешние аспекты на уровне ОС входят в картину, например системные службы, но вы получите эту проблему с большинством сценариев языки.

попытка поймать сигналы, как кто-то здесь предложил в PHP userland, не является хорошей идеей. Прочитайте документацию на pcntl_signal() тщательно, и вы быстро узнаете, что PHP обрабатывает сигналы, используя некоторые довольно неприятные методы (в частности, "тики"), которые пережевывают кучу циклов для чего-то, что редко видят процессы (т. е. сигналы). Обработка сигналов в PHP также едва доступна на платформах POSIX, и поддержка отличается в зависимости от версии PHP. Это изначально звучит как достойное решение, но оно не очень полезно.

PHP также становится все лучше о проблемах с утечкой памяти с течением времени. Вы все еще должны быть осторожны (парсер DOM XML имеет тенденцию к утечке все еще), но я редко вижу убегающие процессы в эти дни, и PHP-трекер довольно тихий по сравнению с прошлыми днями.

Как уже упоминалось, запуск PHP в качестве демона довольно прост и может быть выполнен с помощью одной строки команды. Но актуальной проблемой является поддержание его работы и управления ею. У меня была такая же проблема довольно давно, и хотя уже есть много доступных решений, большинство из них имеют множество зависимостей или трудны в использовании и не подходят для основных применений. Я написал сценарий оболочки, который может управлять любым процессом/приложением, включая скрипты php cli. Оно может быть установлен в качестве cronjob для запуска приложения и будет содержать приложение и управлять им. Если он выполняется снова, например, через тот же cronjob, он проверяет, запущено ли приложение или нет, если это так, то просто выходит и позволяет своему предыдущему экземпляру продолжать управлять приложением.

EasyDeamonizer

просто наблюдает за вашей применение (старт, рестарт, журнал, монитор, etc). универсальный сценарий, чтобы убедиться, что приложение работает правильно. Намеренно он использует имя процесса instread файла pid/lock, чтобы предотвратить все его побочные эффекты и сохранить сценарий как можно более простым и stirghforward, поэтому он всегда работает даже при перезапуске самого EasyDaemonizer. Особенности

Прежде, чем начать: я знаю, что такое phpDaemon и System_Daemon. Я читал статьи по этой тематике, и на хабре тоже.

  • Запускаться из консоли и отвязываться от неё
  • Всю информацию писать в логи, ничего не выводить в консоль
  • Уметь плодить дочерние процессы и контролировать их
  • Выполнять поставленную задачу
  • Корректно завершать работу

Отвязываемся от консоли


Функция pcntl_fork() создает дочерний процесс и возвращает его идентификатор. Однако переменная $child_pid в дочерний процесс не попадает (точнее она будет равна 0), соответственно проверку пройдет только родительский процесс. Он завершится, а дочерний процесс продолжит выполнение кода.

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

Переопределяем вывод

Здесь мы закрываем стандартные потоки вывода и направляем их в файл. STDIN на всякий случай открываем на чтение из /dev/null, т.к. наш демон не будет читать из консоли — он от неё отвязан. Теперь весь вывод нашего демона будет логироваться в файлах.

Поехали!

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

DaemonClass.php

Мы ожидаем сигналы SIGTERM (завершения работы) и SIGCHLD (от дочерних процессов). Запускаем бесконечный цикл, чтобы демон не завершился. Проверяем, можно ли создать еще дочерний процесс и ждем, если нельзя.


pcntl_fork() возвращает -1 в случае возникновения ошибки, $pid будет доступна в родительском процессе, в дочернем этой переменной не будет (точнее она будет равна 0).


SIGTERM — сигнал корректного завершения работы. SIGCHLD — сигнал завершения работы дочернего процесса. При завершении дочернего процесса мы удаляем его из списка запущенных процессов. При получении SIGTERM, выставляем флаг — наш «бесконечный цикл» завершится, когда выполнится текущая задача.

Осталось запретить запуск нескольких копий демона, об это отлично написано в этой статье.

Спасибо за внимание.

UPD: хабраюзер Dlussky в своем комментарии подсказал, что в PHP >= 5.3.0 вместо declare(ticks = 1) надо бы использовать pcntl_signal_dispatch()

Демон - это программа в системах класса UNIX, запускаемая самой системой и работающая в фоновом режиме без прямого взаимодействия с пользователем. Если это понятие применить к нашей задаче, т.е. к языку программирования PHP, то можно сделать следующие выводы: Демон - это обычный PHP скрипт выполняемый интерпретатором. PHP демон работает на сервере в фоновом режиме и не взаимодействует на прямую с пользователем.

Самый простой вариант реализации

Применимо к PHP, это скрипт, который может работать самостоятельно, без остановок и без участия пользователя. Как получить такой скрипт? На самом деле, очень просто, нужно лишь нарушить одно из первых правил программирования, которому учат в школе, и создать бесконечный цикл:

Простой до невозможности код вызывает, всё же, несколько вопросов. Как его запустить? Как отслеживать его выполнение? Как его остановить?

Как запустить php-демона

А как вообще запускают php-скрипты? Если это веб-приложение, то при помощи браузера и веб-сервера. Но этот вариант не подходит, ведь мы имеем дело с бесконечным скриптом, а время выполнения скриптов ограничены директивой max_execution_time в php.ini. Следовательно, бесконечный скрипт необходимо запускать через консоль, ведь тогда максимальное время его выполнения не учитывается. Примерно так выглядит команда запуска демона:

Для ручного запуска её нужно ввести в ssh терминале (putty, WinSCP и т.д.), а для запуска системой при загрузке - в соответствующий файл автозагрузки (положение и название файла зависит от операционной системы). Обратите внимание, что консольный скрипт демона запускается в фоновом режиме, не вовлекая пользователя в ожидание его завершения (ведь скрипт бесконечен). Именно в наличии возможности запустить процесс в фоновом режиме и лежит причина того, что описываемый мной способ не подходит для Windows-серверов. После запуска в консоли должен отобразиться идентификатор процесса нашего демона, так называемый PID.

Отслеживание и остановка демонов

Проверить, запущен ли процесс демона можно просто открыв список процессов в системе:

Найти демона в списке процессов несложно, как по команде запуска, так и по PID:

Остановить процесс демона можно так же, как и любой другой процесс:

В приведённом примере xxxx - это и есть PID, идентификатор процесса.

Улучшаем реализацию. Вариант решения через расширение PCNTL

Для реализации демона на php нам понадобится расширение PCNTL. Данное расширение дает возможность управлять запущенными процессами. Убедились, что данное расширение присутствует на Вашем сервере! Тогда рассмотрим каркас простейшего демона.

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

Бесконечный цикл реализован при помощи конструкции while и переменной $stop. Данная переменная нам необходима для корректного завершения процесса, например, так:

В данном примере демон за 20 секунд создает 10 файлов и присваивает переменной $stop значение true, на следующей итерации бесконечный цикл while прекратится и программа завершит работу. В данном примере мы рассмотрели однопроцессорный демон на языке программирования PHP

Запуск демона

Для запуска подключаемся по SSH и запускаем скрипт:

Добавим обработку сигналов в скрипте

Поддержание уникальности демона

Обычно для этих целей используются т.н. .pid-файлы — файл, в котором записан pid данного конкретного демона, если он запущен.

А после демонизации — нужно записать в pid-файл текущий PID демона.

Контролирование процессов

Контролировать процессы можно через Supervisor

Настройка Supervisor состоит из двух частей: конфигурационного файла supervisord и самой программы, предназначенной для постоянного выполнения в фоне.

Конфиг сервиса

Чтобы Supervisor увидел новый сервис нужно перезапустить его самого.

$ sudo service supervisor restart

Для проверки перезапустим сервис и остановим его, подождав немного:

Что ещё нужно иметь ввиду?

После обновления исходных кодов нужно обязательно перезапускать все подобные сервисы чтобы они использовали новую кодовую базу. Это можно делать прямо из хука post-receive или из Makefile, если такой используется для сборки ресурсов после выгрузки новый версии.

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

Ответ 1

Вы можете запустить свой php-скрипт из командной строки (т . е . bash), используя:

nohup php myscript.php &

«&» переводит ваш процесс в фоновый режим.

Ответ 2

Запуск и остановка вашего демона:

sudo service myphpworker start

sudo service myphpworker stop

Проверьте, запущен ли ваш демон:

sudo service myphpworker status

Ответ 3

Ответ 4

Ответ 5

  1. Автоматический запуск демона при перезагрузке .

  2. Автоматический перезапуск демона при сбое .

  3. Ведение журнала, включая перенос и обрезку.

  4. Интерфейс управления: 'svc' и 'svstat' .

  5. Дружественный к UNIX (возможно, не для всех это плюс) .

Ответ 6

Существует несколько способов решения этой проблемы. Я не знаю вашей специфики, но, возможно, есть другой способ запустить процесс PHP. Например, если вам нужно, чтобы код выполнялся на основе событий в базе данных SQL, вы можете настроить триггер для выполнения вашего скрипта. Это очень просто сделать в PostgreSQL: http://www.postgresql.org/docs/current/static/external-pl.html.

Я думаю, что лучше всего создать процесс D ae mon с помощью nohup. Nohup, который позволяет команде продолжать выполняться даже после того, как пользователь вышел из системы:

nohup php myscript.php &

Однако существует очень серьезная проблема. Менеджер памяти PHP был создан в предположении, что скрипт выполняется всего несколько секунд, а затем прекращает свое существование. Ваш PHP скрипт начнет использовать ГИГАБАЙТЫ памяти уже через несколько дней. Вы ДОЛЖНЫ также создать скрипт cron, который запускается каждые 12 или, может быть, 24 часа, который завершает и снова запускает ваш php-скрипт следующим образом:

killall -3 php

nohup php myscript.php &

Но что, если сценарий находится в процессе работы? Ну, kill -3 — это прерывание, это то же самое, что нажать ctrl+c в CLI. Ваш php-скрипт может поймать это прерывание и выйти из него, используя библиотеку PHP pcntl: http://php.oregonstate.edu/manual/en/function.pcntl-signal.php. Например, так:

function clean_up()

GLOBAL $lock;

mysql_close();

fclose($lock)

exit();

>

pcntl_signal(SIGINT, 'clean_up');

Идея $lock заключается в том, что PHP-скрипт может открыть файл с помощью fopen("file", "w");. Только один процесс может иметь блокировку записи в файл, поэтому с помощью этого вы можете убедиться, что запущена только одна копия вашего PHP-скрипта.

Ответ 7

Мы будем очень благодарны

если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.

Читайте также: