Comment exécuter un script Python en arrière-plan et le redémarrer après un crash?

10

J'ai un script Python très simple que j'aimerais toujours exécuter sur mon serveur Ubuntu 12.04. J'ai pensé à utiliser upstart + monit. Le problème est que ces outils semblent plutôt compliqués pour un simple mortel comme moi, et je ne trouve pas d'exemple simple sur le web.

Est-ce que upstart + monit est exagéré? Quelqu'un connaît-il une alternative plus simple ou un bon tutoriel pour upstart + monit? Si je veux juste être sûr que le script est toujours en cours d'exécution, monit est-il requis?

sebpiq
la source
Pour référence, exactement la même question a été posée ici: superuser.com/q/461546/786969
PHPirate

Réponses:

16

Le moyen le plus simple de le faire est de le placer dans /etc/init/something.conf:

start on runlevel [2345]
stop on runlevel [016]

respawn
exec python /path/to/your/script.py

Respawn le redémarrera s'il est tué ou sort non nul (comme une exception non capturée). Cela fonctionnera depuis Ubuntu 10.04.

Si vous avez 12.04, vous pouvez devenir plus sophistiqué. Ce qui précède exécutera votre script en tant que root. Dans 12.04, vous pouvez ajouter setuid / setgid:

start on runlevel [2345]
stop on runlevel [016]

respawn
setuid nobody
setgid nogroup
exec python /path/to/your/python.py

Si votre script se termine alors qu'il n'y a pas de réseau disponible et que vous prévoyez de l'exécuter sur une connexion réseau instable, vous devez le corriger et le faire rester en vie / réessayer. Mais si vous ne le pouvez pas, vous devrez peut-être également le faire démarrer manuellement chaque fois qu'un périphérique réseau apparaît. Vous pouvez donc le placer dans /etc/network/if-up.d/yourscript(le rendre exécutable avec chmod + x)

#!/bin/sh
exec start wait-for-state WAITER=$IFACE-yourscript WAIT_FOR=something

Où votre script est juste quelque chose d'arbitraire et unique à ce script particulier, et "quelque chose" est le même que le nom du travail (tel que /etc/init/something.confsuggéré plus haut).

SpamapS
la source
Ouais ! Donc, cela utilise à upstartdroite? Est-ce à dire que le script sera également lancé au démarrage (ce qui serait bien!)? Et respawnest-ce suffisant pour que vous n'ayez pas besoin de configurer monit?
sebpiq
Oui, le «démarrage au niveau d'exécution [2345]» signifie au moment où le système passe en «mode multi-utilisateur». À long terme, un plan est en train de se former pour remplacer le très ancien "niveau d'exécution" unixy par des choses comme "démarrer au démarrage des services réseau" et "arrêter à arrêter les services réseau" afin qu'il soit plus logique.
SpamapS
Impressionnant ! Merci beaucoup, c'est exactement ce dont j'avais besoin.
sebpiq
2

L'approche habituelle de l'ancien temps était d'écrire un fichier contenant un horodatage ou l'ID de processus /tmp, puis de vérifier si cet ID de processus était toujours en cours d'exécution ou respectivement si l'horodatage était encore récent.

Vous pouvez également faire un simple while [ 1 ]; do phyton-script.ph; donequi redémarrerait le script au cas où il reviendrait.

Pour plus de possibilités, veuillez fournir plus d'informations sur votre script. Surtout pourquoi vous vous attendez à ce qu'il se ferme ou se bloque de manière inattendue.

embrouiller
la source
le script supprime simplement les tweets des twitters en utilisant une API de streaming. Donc, fondamentalement, il y a une boucle infinie attendant que les tweets soient poussés, exécutant du code et revenant à l'attente. Je veux juste que ça fonctionne sans souci ... s'il y a un bug et que ça plante, et ainsi de suite ...
sebpiq
Une réponse similaire à la vôtre (que j'ai acceptée): superuser.com/questions/461546/…
sebpiq
Une tâche cron pour vérifier si le script est toujours en cours d'exécution peut également être une bonne idée.
con-f-use