Un'altra opzione è usare Upstart. È stato originariamente sviluppato per Ubuntu (e viene fornito con esso per impostazione predefinita), ma è pensato per essere adatto a tutte le distribuzioni Linux.
Questo approccio è simile a Supervisord e daemontools, in quanto avvia automaticamente il demone all'avvio del sistema e si rigenera al completamento dello script.
Come configurarlo:
Crea un nuovo file di script in /etc/init/myphpworker.conf
. Ecco un esempio:
# Info
description "My PHP Worker"
author "Jonathan"
# Events
start on startup
stop on shutdown
# Automatically respawn
respawn
respawn limit 20 5
# Run the script!
# Note, in this example, if your PHP script returns
# the string "ERROR", the daemon will stop itself.
script
[ $(exec /usr/bin/php -f /path/to/your/script.php) = 'ERROR' ] && ( stop; exit 1; )
end script
Avvio e arresto del tuo demone:
sudo service myphpworker start
sudo service myphpworker stop
Controlla se il tuo demone è in esecuzione:
sudo service myphpworker status
Grazie
Un grande grazie a Kevin van Zonneveld, da cui ho imparato questa tecnica.
Puoi avviare il tuo script php dalla riga di comando (ad es. bash) usando
nohup php myscript.php &
il &
mette il tuo processo in secondo piano.
Modificare:
Sì, ci sono alcuni inconvenienti, ma non è possibile controllarli? È semplicemente sbagliato.
Un semplice kill processid
lo fermerà. Ed è ancora la soluzione migliore e più semplice.
Con new systemd puoi creare un servizio.
Devi creare un file o un collegamento simbolico in /etc/systemd/system/
, per esempio. myphpdaemon.service e inserisci contenuti come questo, myphpdaemon sarà il nome del servizio:
[Unit]
Description=My PHP Daemon Service
#May your script needs MySQL or other services to run, eg. MySQL Memcached
Requires=mysqld.service memcached.service
After=mysqld.service memcached.service
[Service]
User=root
Type=simple
TimeoutSec=0
PIDFile=/var/run/myphpdaemon.pid
ExecStart=/usr/bin/php -f /srv/www/myphpdaemon.php arg1 arg2> /dev/null 2>/dev/null
#ExecStop=/bin/kill -HUP $MAINPID #It's the default you can change whats happens on stop command
#ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
StandardOutput=null #If you don't want to make toms of logs you can set it null if you sent a file or some other options it will send all PHP output to this one.
StandardError=/var/log/myphpdaemon.log
[Install]
WantedBy=default.target
Sarai in grado di avviare, ottenere lo stato, riavviare e arrestare i servizi utilizzando il comando
systemctl <start|status|restart|stop|enable> myphpdaemon
Puoi usare il server nativo PHP usando php -S 127.0.0.1:<port>
oppure eseguilo come script. Usando uno script PHP dovresti avere una sorta di "ciclo continuo" per continuare a funzionare.
<?php
gc_enable();//
while (!connection_aborted() || PHP_SAPI == "cli") {
//Code Logic
//sleep and usleep could be useful
if (PHP_SAPI == "cli") {
if (rand(5, 100) % 5 == 0) {
gc_collect_cycles(); //Forces collection of any existing garbage cycles
}
}
}
Esempio funzionante:
[Unit]
Description=PHP APP Sync Service
Requires=mysqld.service memcached.service
After=mysqld.service memcached.service
[Service]
User=root
Type=simple
TimeoutSec=0
PIDFile=/var/run/php_app_sync.pid
ExecStart=/bin/sh -c '/usr/bin/php -f /var/www/app/private/server/cron/app_sync.php 2>&1 > /var/log/app_sync.log'
KillMode=mixed
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=default.target
Se la tua routine PHP deve essere eseguita una volta in un ciclo (come un diggest) puoi utilizzare uno script shell o bash da richiamare nel file di servizio systemd anziché direttamente in PHP, ad esempio:
#!/usr/bin/env bash
script_path="/app/services/"
while [ : ]
do
# clear
php -f "$script_path"${1}".php" fixedparameter ${2} > /dev/null 2>/dev/null
sleep 1
done
Se hai scelto queste opzioni dovresti cambiare il KillMode in mixed
ai processi, bash(main) e PHP(child) vengano uccisi.
ExecStart=/app/phpservice/runner.sh phpfile parameter > /dev/null 2>/dev/null
KillMode=process
This method also is effective if you're facing a memory leak.
Nota:ogni volta che modifichi "myphpdaemon.service" devi eseguire `systemctl daemon-reload', ma non preoccuparti se non lo fai, verrà avvisato quando è necessario.