Necesito ejecutar un script php como proceso daemon (esperar instrucciones y hacer cosas). cron job no lo hará por mí porque se deben tomar medidas tan pronto como llegue la instrucción. Sé que PHP no es realmente la mejor opción para los procesos de daemon debido a problemas de administración de memoria, pero debido a varias razones, tengo que usar PHP en este caso. Me encontré con una herramienta de libslack llamada Daemon ( http://libslack.org/daemon ) que parece ayudarme a administrar los procesos de daemon, pero no ha habido actualizaciones en los últimos 5 años, así que me pregunto si conoces algunas Otras alternativas adecuadas para mi caso. Cualquier información será realmente apreciada.
154
Respuestas:
Puede iniciar su script php desde la línea de comando (es decir, bash) utilizando
nohup php myscript.php &
el
&
pone su proceso en segundo plano.Editar:
Sí, hay algunos inconvenientes, pero ¿no es posible controlarlos? Eso está mal.
Un simple
kill processid
lo detendrá. Y sigue siendo la mejor y más simple solución.fuente
nohup
y&
hace lo mismo: desconectando el proceso iniciado de la actual integridad del shell. ¿Por qué los necesito a ambos? ¿No puedo simplemente hacerphp myscript.php &
onohup myscript.php
?? Graciasnohup php myscript.php > myscript.log &
Otra opción es usar Upstart . Fue desarrollado originalmente para Ubuntu (y viene empaquetado con él de manera predeterminada), pero está diseñado para ser adecuado para todas las distribuciones de Linux.
Este enfoque es similar a Supervisord y daemontools , ya que automáticamente inicia el demonio al arrancar el sistema y reaparece al completar el script.
Cómo configurarlo:
Cree un nuevo archivo de script en
/etc/init/myphpworker.conf
. Aquí hay un ejemplo:Iniciar y detener tu demonio:
Comprueba si tu demonio se está ejecutando:
Gracias
Muchas gracias a Kevin van Zonneveld , de donde aprendí esta técnica.
fuente
sudo service myphpworker start/stop/status
solo funciona con servicios que no se encuentran en/etc/init.d
servicios nuevos. @ matt-sich parece haber descubierto la sintaxis correcta. Otra opción es usar Gearman o Resque, que permite el procesamiento en segundo plano y la desamonización.Con nuevo systemd puedes crear un servicio.
Debe crear un archivo o un enlace simbólico en
/etc/systemd/system/
, por ejemplo. myphpdaemon.service y colocar contenido como este, myphpdaemon será el nombre del servicio:Podrá iniciar, obtener el estado, reiniciar y detener los servicios con el comando
systemctl <start|status|restart|stop|enable> myphpdaemon
El script PHP debería tener una especie de "bucle" para continuar ejecutándose.
Ejemplo de trabajo:
Si su rutina PHP debe ejecutarse una vez en un ciclo (como un diggest), puede usar un script de shell o bash para invocarlo en el archivo de servicio systemd en lugar de PHP directamente, por ejemplo:
Si elige esta opción, debe cambiar KillMode a
mixed
procesos, bash (main) y PHP (child) se eliminarán.This method also is effective if you're facing a memory leak.
fuente
systemctl status <your_service_name> -l
salida, le dará una pista de lo que está sucediendo.Si puede, tome una copia de la Programación avanzada en el entorno UNIX . Todo el capítulo 13 está dedicado a la programación de demonios. Los ejemplos están en C, pero todas las funciones que necesita tienen envoltorios en PHP (básicamente pcntl y posix extensiones ).
En pocas palabras, escribir un demonio (esto solo es posible en sistemas operativos basados en * nix - Windows usa servicios) es así:
umask(0)
para evitar problemas de permisos.fork()
y que el padre salga.setsid()
.SIGHUP
(generalmente esto se ignora o se usa para indicar al demonio que vuelva a cargar su configuración) ySIGTERM
para indicarle al (para indicarle al proceso que salga con gracia).fork()
de nuevo y que el padre salga.chdir()
.fclose()
stdin
,stdout
Ystderr
y no escribir en ellos. La forma correcta es redirigirlos a/dev/null
o a un archivo, pero no pude encontrar una manera de hacerlo en PHP. Es posible cuando ejecutas el demonio para redirigirlos usando el shell (tendrás que descubrir cómo hacerlo, no lo sé :).Además, dado que está utilizando PHP, tenga cuidado con las referencias cíclicas, ya que el recolector de basura PHP, antes de PHP 5.3, no tiene forma de recopilar esas referencias y el proceso perderá memoria, hasta que finalmente se bloquee.
fuente
Ejecuto una gran cantidad de demonios PHP.
Estoy de acuerdo con usted en que PHP no es el mejor (o incluso un buen) lenguaje para hacer esto, pero los demonios comparten código con los componentes orientados a la web, por lo que, en general, es una buena solución para nosotros.
Utilizamos daemontools para esto. Es inteligente, limpio y confiable. De hecho, lo usamos para ejecutar todos nuestros demonios.
Puede consultar esto en http://cr.yp.to/daemontools.html .
EDITAR: una lista rápida de características.
fuente
Usted puede
nohup
como Henrik sugirió.screen
y ejecute su programa PHP como un proceso regular dentro de eso. Esto te da más control que usarnohup
.Recomendaría el método más simple (pantalla en mi opinión) y luego, si desea más características o funcionalidad, vaya a métodos más complejos.
fuente
Hay más de una forma de resolver este problema.
No conozco los detalles, pero quizás haya otra forma de activar el proceso PHP. Por ejemplo, si necesita que el código se ejecute en función de eventos en una base de datos SQL, puede configurar un disparador para ejecutar su script. Esto es realmente fácil de hacer en PostgreSQL: http://www.postgresql.org/docs/current/static/external-pl.html .
Honestamente, creo que tu mejor opción es crear un proceso Damon usando nohup. nohup permite que el comando continúe ejecutándose incluso después de que el usuario haya cerrado sesión:
Sin embargo, hay un problema muy grave. Como dijiste, el administrador de memoria de PHP es una basura completa, se construyó con la suposición de que un script solo se ejecuta durante unos segundos y luego existe. Su script PHP comenzará a usar GIGABYTES de memoria después de solo unos días. TAMBIÉN DEBE crear un script cron que se ejecute cada 12 o tal vez 24 horas que mate y vuelva a generar su script php de esta manera:
Pero, ¿y si el guión estuviera en el medio de un trabajo? Bueno, kill -3 es una interrupción, es lo mismo que hacer un ctrl + c en la CLI. Su script php puede detectar esta interrupción y salir con gracia utilizando la biblioteca PHP pcntl: http://php.oregonstate.edu/manual/en/function.pcntl-signal.php
Aquí hay un ejemplo:
La idea detrás del $ lock es que el script PHP puede abrir un archivo con un fopen ("archivo", "w") ;. Solo un proceso puede tener un bloqueo de escritura en un archivo, por lo que puede asegurarse de que solo se esté ejecutando una copia de su script PHP.
¡Buena suerte!
fuente
Kevin van Zonneveld escribió un artículo detallado muy agradable sobre esto , en su ejemplo utiliza el
System_Daemon
paquete PEAR (última fecha de lanzamiento el 2009-09-02).fuente
Echa un vistazo a https://github.com/shaneharter/PHP-Daemon
Esta es una biblioteca de demonios orientada a objetos. Tiene soporte incorporado para cosas como el registro y la recuperación de errores, y tiene soporte para crear trabajadores en segundo plano.
fuente
Recientemente tuve la necesidad de una solución multiplataforma (Windows, Mac y Linux) para el problema de ejecutar scripts PHP como demonios. Resolví el problema escribiendo mi propia solución basada en C ++ y creando binarios:
https://github.com/cubiclesoft/service-manager/
Soporte completo para Linux (a través de sysvinit), pero también servicios de Windows NT y Mac OSX lanzados.
Si solo necesita Linux, entonces algunas de las otras soluciones presentadas aquí funcionan lo suficientemente bien y, dependiendo del sabor. También hay Upstart y systemd en estos días, que tienen retrocesos para sysvinit scripts. Pero la mitad del punto de usar PHP es que es de naturaleza multiplataforma, por lo que el código escrito en el lenguaje tiene una muy buena posibilidad de funcionar en todas partes tal como está. Las deficiencias comienzan a aparecer cuando ciertos aspectos externos del nivel del sistema operativo nativo entran en escena, como los servicios del sistema, pero obtendrá ese problema con la mayoría de los lenguajes de secuencias de comandos.
Intentar captar señales como alguien aquí sugirió en PHP userland no es una buena idea. Lea la documentación
pcntl_signal()
detenidamente y aprenderá rápidamente que PHP maneja señales usando algunos métodos bastante desagradables (específicamente, 'ticks') que mastican un montón de ciclos para algo raramente visto por los procesos (es decir, señales). El manejo de señales en PHP también está apenas disponible en las plataformas POSIX y el soporte difiere según la versión de PHP. Inicialmente suena como una solución decente, pero no llega a ser realmente útil.PHP también ha mejorado con respecto a los problemas de pérdida de memoria a medida que pasa el tiempo. Todavía debe tener cuidado (el analizador DOM XML tiende a filtrarse aún), pero en estos días rara vez veo procesos fuera de control y el rastreador de errores de PHP es bastante silencioso en comparación con los días anteriores.
fuente
Como otros ya han mencionado, ejecutar PHP como demonio es bastante fácil y se puede hacer usando una sola línea de comando. Pero el problema real es mantenerlo en funcionamiento y administrarlo. He tenido el mismo problema hace bastante tiempo y, aunque ya hay muchas soluciones disponibles, la mayoría de ellas tienen muchas dependencias o son difíciles de usar y no son adecuadas para usos básicos. Escribí un script de shell que puede administrar cualquier proceso / aplicación, incluidos los scripts PHP cli. Se puede configurar como cronjob para iniciar la aplicación y contendrá la aplicación y la administrará. Si se ejecuta nuevamente, por ejemplo a través del mismo cronjob, verifica si la aplicación se está ejecutando o no, si lo hace, simplemente se cierra y deja que su instancia anterior continúe administrando la aplicación.
Lo cargué en github, siéntase libre de usarlo: https://github.com/sinasalek/EasyDeamonizer
EasyDeamonizer
Simplemente vigila su aplicación (inicio, reinicio, registro, monitor, etc.). un script genérico para asegurarse de que su aplicación siga ejecutándose correctamente. Intencionalmente utiliza el nombre de proceso instread del archivo pid / lock para evitar todos sus efectos secundarios y mantener el script lo más simple y dinámico posible, por lo que siempre funciona incluso cuando se reinicia EasyDaemonizer. Caracteristicas
fuente
Ampliando la respuesta de Emil Ivaov , puede hacer lo siguiente para cerrar STDIN, STDOUT AND STDERROR en php
Básicamente, cierra las transmisiones estándar para que PHP no tenga lugar para escribir. Las siguientes
fopen
llamadas establecerán el IO estándar en/dev/null
.He leído esto del libro de Rob Aley - PHP más allá de la web
fuente
Escribí e implementé un simple php-daemon, el código está en línea aquí
https://github.com/jmullee/PhpUnixDaemon
Características: caída de privilegios, manejo de señales, registro
Lo utilicé en un controlador de cola (caso de uso: desencadenar una operación larga desde una página web, sin hacer que la página genere php espere, es decir, inicie una operación asincrónica) https://github.com/jmullee/PhpIPCMessageQueue
fuente
puedes consultar pm2 aquí, http://pm2.keymetrics.io/
cree un archivo ssh, como worker.sh, que se incluirá en su script php con el que tratará.
trabajador.sh
comienzo del demonio
Saludos, eso es todo.
fuente