Script Python en tant que service linux/démon
Bonjour,
J'essaie de laisser un script python s'exécuter en tant que service (daemon) sur (ubuntu) linux.
Sur le web, il existe plusieurs solutions comme:
Http://pypi.python.org/pypi/python-daemon/
Un processus de démon Unix bien comporté est difficile à obtenir, mais les étapes requises sont à peu près les mêmes pour chaque programme de démon. Une instance DaemonContext contient le comportement et l'environnement de processus configuré pour le programme; utilisez l'instance comme gestionnaire de contexte pour entrer un État démon.
Http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
Cependant, comme je veux intégrer mon script python spécifiquement avec ubuntu linux, ma solution est une combinaison avec un init.d script
#!/bin/bash
WORK_DIR="/var/lib/foo"
DAEMON="/usr/bin/python"
ARGS="/opt/foo/linux_service.py"
PIDFILE="/var/run/foo.pid"
USER="foo"
case "$1" in
start)
echo "Starting server"
mkdir -p "$WORK_DIR"
/sbin/start-stop-daemon --start --pidfile $PIDFILE
--user $USER --group $USER
-b --make-pidfile
--chuid $USER
--exec $DAEMON $ARGS
;;
stop)
echo "Stopping server"
/sbin/start-stop-daemon --stop --pidfile $PIDFILE --verbose
;;
*)
echo "Usage: /etc/init.d/$USER {start|stop}"
exit 1
;;
esac
exit 0
Et en python:
import signal
import time
import multiprocessing
stop_event = multiprocessing.Event()
def stop(signum, frame):
stop_event.set()
signal.signal(signal.SIGTERM, stop)
if __name__ == '__main__':
while not stop_event.is_set():
time.sleep(3)
Ma question est maintenant de savoir si cette approche est correcte. Dois-je gérer tout de signaux supplémentaires? Sera-ce un "processus démon Unix bien comporté"?
2 réponses
En supposant que votre démon a un moyen de fonctionner continuellement (une boucle d'événement, twisted, peu importe), vous pouvez essayer d'utiliser upstart
.
Voici un exemple de configuration upstart pour un service Python hypothétique:
description "My service"
author "Some Dude <blah@foo.com>"
start on runlevel [234]
stop on runlevel [0156]
chdir /some/dir
exec /some/dir/script.py
respawn
Si vous enregistrez ce script.conf à /etc/init
vous faites simplement un
$ sudo initctl reload-configuration
$ sudo start script
, Vous pouvez l'arrêter avec stop script
. Ce que dit la conf upstart ci-dessus est de démarrer ce service au redémarrage et de le redémarrer s'il meurt.
En ce qui concerne la gestion du signal-votre processus devrait répondre naturellement à SIGTERM
. Par défaut, cela doit être géré sauf si vous avez spécifiquement installé votre propre gestionnaire de signal.
La réponse de Rloton est bonne. Voici un léger raffinement, juste parce que j'ai passé une tonne de temps à déboguer. Et je dois faire une nouvelle réponse pour pouvoir formater correctement.
Quelques autres points qui m'ont pris une éternité pour déboguer:
- quand il échoue, vérifiez d'abord /var / log/upstart/.log
- Si votre script implémente un démon avec Python-daemon , vous N'utilisez pas la strophe 'expect daemon'. Ne pas "s'attendre" fonctionne. Je ne sais pas pourquoi. (Si quelqu'un sait pourquoi-s'il vous plait post!)
- aussi, continuez à vérifier "initctl status script" pour vous assurer que vous êtes en place (Démarrer / Exécuter). (et faites un rechargement lorsque vous mettez à jour votre fichier conf)
Voici ma version:
description "My service"
author "Some Dude <blah@foo.com>"
env PYTHON_HOME=/<pathtovirtualenv>
env PATH=$PYTHON_HOME:$PATH
start on runlevel [2345]
stop on runlevel [016]
chdir <directory>
# NO expect stanza if your script uses python-daemon
exec $PYTHON_HOME/bin/python script.py
# Only turn on respawn after you've debugged getting it to start and stop properly
respawn