web-dev-qa-db-fra.com

Systemd Restart = n'est toujours pas respecté

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 d'origine:


J'utilise systemd pour garder un script de travail fonctionnel à 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 termine normalement après quelques minutes, j'ai remarqué que s'il échoue à plusieurs reprises au démarrage, systemd abandonnera simplement son démarrage:

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 de 255, systemd renonce à 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'.

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

62
Benjamin

Je voudrais étendre 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 dans StartLimitIntervalSec. Les deux options appartiennent à [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 de redémarrages automatiques pour les unités avec stratégie de redémarrage définie :

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

La réponse de Rahul aide, car le délai plus long empêche d'atteindre le compteur d'erreurs dans le délai StartLimitIntervalSec. La bonne réponse consiste à définir à la fois RestartSec et StartLimitBurst sur des valeurs raisonnables.

62
MarSik

Oui, il y en a. Vous pouvez spécifier de réessayer après x secondes sous [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 que systemd est au courant du nouveau fichier,

systemctl daemon-reload

puis redémarrez le service pour activer les modifications,

systemctl restart test

Comme vous l'avez demandé, en regardant la documentation,

Restart=on-failure

sonne comme une recommandation décente.

41
Rahul

systemd renonce à essayer de le redémarrer

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

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

Ceci limite le débit.

La durée du petit moment est spécifiée dans l'unité de service, à l'aide de StartLimitIntervalSec= réglage. 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 StartLimitBurst= réglage. Si rien sur votre système ne diffère de Vanilla systemd, y compris les valeurs par défaut pour ces deux paramètres, alors c'est 5 fois en 10 secondes.

StartLimitIntervalSec=0 désactive la limitation de débit, donc systemd réessayera pour toujours plutôt que d'abandonner. Mais faire en sorte que votre service ne soit pas interrompu si souvent, ou suffisamment inactif entre les sorties et les redémarrages pour ne pas dépasser le seuil de limitation de débit, est une meilleure approche.

Notez que la limitation du taux ne se soucie pas de la façon dont votre service s'est arrêté. Il déclenche le nombre de tentatives de démarrage/redémarrage, quelle que soit leur cause.

Lectures complémentaires

5
JdeBP