Systemd Restart = n'est toujours pas honoré

54

Remarque: j'ai écrit un article sur Medium qui explique comment créer un service et comment éviter ce problème particulier: Création d'un service Linux avec systemd .

Question originale:


J'utilise systemd pour garder un script de travail actif à tout moment:

[Unit]
Description=My worker
After=mysqld.service

[Service]
Type=simple
Restart=always
ExecStart=/path/to/script

[Install]
WantedBy=multi-user.target

Bien que le redémarrage fonctionne correctement si le script se ferme normalement après quelques minutes, j'ai remarqué que s'il échouait à plusieurs reprises au démarrage, il systemdcesserait simplement d'essayer de le démarrer:

Jun 14 11:10:31 localhost systemd[1]: test.service: Main process exited, code=exited, status=1/FAILURE
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'exit-code'.
Jun 14 11:10:31 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.
Jun 14 11:10:31 localhost systemd[1]: test.service: Start request repeated too quickly.
Jun 14 11:10:31 localhost systemd[1]: Failed to start My worker.
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'start-limit'.

De même, si mon script de travail échoue plusieurs fois avec un état de sortie égal à 255, systemdrenonce à essayer de le redémarrer:

Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'exit-code'.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Start request repeated too quickly.  
Jun 14 11:25:51 localhost systemd[1]: Failed to start My worker.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Unit entered failed state.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'start-limit'.

Y a-t-il un moyen de forcer systemdà toujours réessayer après quelques secondes?

Benjamin
la source

Réponses:

53

Je voudrais prolonger un peu la réponse de Rahul.

SystemD essaie de redémarrer plusieurs fois ( StartLimitBurst) et arrête d'essayer si le nombre de tentatives est atteint StartLimitIntervalSec. Les deux options appartiennent à la [unit]section.

Le délai par défaut entre les exécutions est de 100 ms ( RestartSec), ce qui permet d’atteindre très rapidement la limite de débit.

SystemD ne tentera plus jamais de redémarrage automatique pour les unités pour lesquelles une stratégie de redémarrage est définie :

Notez que les unités configurées pour Restart=et qui atteignent la limite de démarrage ne sont plus essayées. Cependant, ils peuvent toujours être redémarrés manuellement à un moment ultérieur. À partir de ce moment, la logique de redémarrage est à nouveau activée.

La réponse de Rahul est utile, car le délai plus long empêche d'atteindre le compteur d'erreurs dans le délai StartLimitIntervalSecimparti. La bonne réponse consiste à définir les deux RestartSecet StartLimitBurstsur des valeurs raisonnables.

MarSik
la source
5
Maintenant que je comprends (enfin) comment ça marche, après quelques essais, je peux voir que votre réponse est la plus correcte. En bout de ligne pour moi: set StartLimitIntervalSec=0and voilà.
Benjamin
35

Oui , il y a. Vous pouvez spécifier de réessayer après xquelques secondes dans la [Service]section,

[Service]
Type=simple
Restart=always
RestartSec=3
ExecStart=/path/to/script

Après avoir enregistré le fichier, vous devez recharger les configurations du démon pour vous assurer qu’il systemdest au courant du nouveau fichier.

systemctl daemon-reload

puis redémarrez le service pour activer les modifications,

systemctl restart test

Comme vous avez demandé, en regardant la documentation,

Restart=on-failure

sonne comme une recommandation décente.

Rahul
la source
Cela semble bien fonctionner, merci! Donc, pour mieux comprendre cela, sans RestartSecdirective, systemdplusieurs tentatives de redémarrage redémarrent très rapidement, puis entrent dans un état d'échec permanent; quelque chose qui ne peut pas arriver quand RestartSecest spécifié?
Benjamin
De plus, j'ai remarqué que cela retarde le redémarrage "normal" de mon travailleur (je quitte volontairement le travailleur après quelques minutes); y a-t-il un moyen de ne retarder qu'un redémarrage échoué ?
Benjamin
@Benjamin voir mes mises à jour
Rahul
@ Benjamin, vous pouvez vérifier ici pour plus de paramètres.
Rahul
3
À en juger par le doc , alwaysc'est un sur-ensemble de on-failure, donc ça ne va pas aider!
Benjamin
5

systemd abandonne essayer de le redémarrer

Non, systemd renonce à essayer de le redémarrer pendant un moment . Ceci est clairement indiqué dans le journal que vous fournissez:

14 juin 11:25:51 localhost systemd [1]: test.service: Echec avec le résultat 'start-limit' .

C’est une limitation du taux d’entrée en vigueur.

La durée du peu de temps est spécifiée dans l'unité de service à l'aide du StartLimitIntervalSec=paramètre. Le nombre de démarrages nécessaires dans cet intervalle pour déclencher le mécanisme de limitation de débit est spécifié via le StartLimitBurst=paramètre. Si rien sur votre système ne diffère de vanilla systemd, y compris les valeurs par défaut pour ces deux paramètres, le délai est de 5 fois inférieur à 10 secondes.

StartLimitIntervalSec=0désactive la limitation du taux, ainsi systemd réessayera pour toujours plutôt que d'abandonner. Toutefois, il est préférable de ne pas quitter le service trop souvent ou de le laisser suffisamment inactif entre les sorties et les redémarrages pour qu'il ne dépasse pas le seuil de limitation de débit.

Notez que la limitation du débit ne tient pas compte de la façon dont votre service est abandonné. Il déclenche le nombre de tentatives de démarrage / redémarrage, quelle qu'en soit la cause.

Lectures complémentaires

JdeBP
la source
5
Il semble y avoir abandon permanent, cependant: "Actif: échoué (Résultat: limite de départ) depuis Wed 2016-06-15 01:21:24 CEST; il y a 12h". Il reste dans cet état et le script n'est jamais exécuté à nouveau. J'ai essayé de régler manuellement StartLimitIntervalSec=10et StartLimitIntervalSec=5, pas de chance.
Benjamin
5
Il abandonne définitivement par défaut. Voir github.com/systemd/systemd/issues/2416 .
Adam Goode
2
En bout de ligne: pour arrêter l'empêcher d'abandonner définitivement, réglez StartLimitIntervalSec=0.
Benjamin