Comment contrôler le taux de redémarrage automatique d'un service runit?

8

J'ai ce service runit avec runet les log/runscripts fonctionnent correctement.

En l'occurrence, le service lui-même peut se bloquer pour des raisons externes et peut ne pas pouvoir démarrer pendant plusieurs minutes. Par défaut, runit gère cette situation en redémarrant le service toutes les deux secondes. Comment changer ce comportement?

Ma dernière idée a été d'ajouter un checkscript et d'y faire de la magie, mais cela semble beaucoup plus compliqué qu'il ne devrait l'être. Existe-t-il un meilleur moyen plus simple?

jpbochi
la source

Réponses:

3

Je ne connais pas cette fonctionnalité, cependant, si c'était ma tâche de résoudre ce problème, et une lecture de page de manuel très courte n'offrait pas un simple bouton pour régler ce comportement, je ferais ce qui suit:

Étendez le script de démarrage du service existant ou, si cela est fastidieux, insérez un nouveau script de démarrage dans la chaîne (qui à son tour démarre le script de démarrage d'origine). Au lieu de démarrer le service immédiatement, le nouveau script de démarrage doit vérifier si le dernier démarrage s'est produit assez récemment. Cela peut être fait en vérifiant un fichier de signalisation créé par le démarrage précédent. Si le fichier n'existe pas, le script peut continuer et toucher le fichier et démarrer le service. Si le fichier existe, le script doit vérifier si le fichier est suffisamment ancien. S'il n'est pas assez vieux, il devrait attendre (dormir) en boucle jusqu'à ce que le fichier soit assez vieux.

Quelque chose comme ça pourrait fonctionner (attend au moins 1 minute entre les redémarrages):

#!/bin/bash

SIGNALDIR=/tmp
SIGNALFILE=service.started

while /bin/true; do
        found=`find "${SIGNALDIR}" -maxdepth 1 -name "${SIGNALFILE}" -mmin -1 | wc -l`
        [ "${found}" -eq 0 ] && break
        echo "Waiting"
        sleep 10
done

touch "${SIGNALDIR}/${SIGNALFILE}"
original service start...
Laszlo Valko
la source
Voilà une bonne approche. Dès que je l'ai testé, je vais le script avec les éventuelles corrections nécessaires.
jpbochi
8

Vous devez limiter la fréquence de vos redémarrages dans le ./finishfichier de ce service, qui s'exécute en cas de fin anormale. Le ./finishscript recevra le code de retour de ./runet à partir de là, vous pouvez déterminer quoi faire, etc. Pour cette question, vous devriez avoir votre ./finishscript criant fort sur les échecs et envoyer des notifications et sauter tout autour du feu ...

Avery Payne
la source
Merci, c'est la bonne réponse, mais malheureusement, les programmeurs modernes utilisant python, ruby, etc. semblent toujours écrire des applications qui ne prêtent aucune attention aux signaux Unix et ne fournissent pas du tout de codes de sortie appropriés.
figtrap
1
Les codes d'erreur renvoyés sont apparemment "non cool", je suppose?
Avery Payne
semble comme ça. Je pense que c'est un grand pas en arrière, moi-même.
figtrap
1

Je ne suis vraiment pas un fan de la gestion des processus basée sur init (et runit est fondamentalement un substitut init). Comme vous le découvrez, le redémarrage simple des processus ayant échoué dès leur mort n'est pas une stratégie particulièrement bonne. J'ai utilisé init pour redémarrer monit, mais c'est aussi loin que ça. (potentiellement un tueur OOM pourrait tuer monit).

Donc, je vous encourage à chercher un remplaçant plutôt qu'à réparer les choses.

Monit est assez vieux, mais il fait bien le travail, et je ne suis pas au courant que quelque chose de mieux soit arrivé. Il a la fonctionnalité intéressante de ne pas avoir besoin de malloc plus de mémoire après le démarrage, donc bat l'enfer de tout ce qui est écrit dans un langage de script. La dernière chose que vous voulez, c'est que votre moniteur de processus meure car il ne peut pas obtenir de mémoire.

mc0e
la source
systemd, inclus dans EL7 et la plupart des autres distributions, peut gérer nativement cette situation et une variété de situations similaires avec un nombre énorme d'options et rend principalement les gestionnaires de processus comme ceux-ci obsolètes.
Michael Hampton
1
Il existe une petite poignée de situations où systemd peut être "trop ​​grand" pour l'environnement cible. Et l'ancienne méthode de «gestion des processus en redémarrant jusqu'à l'exécution» a été principalement remplacée par une résolution de dépendance appropriée. Voir skarnet.org/software/s6-rc et jjacky.com/anopa pour des exemples.
Avery Payne