Créer ses propres services. vos propres services – Photo de Jeff Sheldon sur UnsplashLorsque j’écris des applications web, j’ai souvent besoin de décharger des tâches lourdes en calcul vers un script worker asynchrone, de planifier des tâches pour plus tard, ou même d’écrire un démon qui écoute un socket pour communiquer directement avec les clients.
Bien qu’il puisse parfois y avoir de meilleurs outils pour ce travail – pensez toujours à utiliser d’abord un logiciel existant, comme un serveur de file d’attente de tâches – écrire votre propre service peut vous donner un niveau de flexibilité que vous n’obtiendrez jamais lorsque vous êtes lié par les contraintes d’un logiciel tiers.
Ce qui est cool, c’est qu’il est assez facile de créer un service Linux : utilisez votre langage de programmation préféré pour écrire un programme à long terme, et transformez-le en service à l’aide de systemd.
Créons un petit serveur en utilisant PHP. Je peux voir vos sourcils se lever, mais cela fonctionne étonnamment bien. Nous allons écouter le port UDP 10000, et renvoyer tout message reçu avec une transformation ROT13 :
Démarrons-le :
$ php server.php
Et testons-le dans un autre terminal :
$ nc -u 127.0.0.1 10000
Hello, world!
Uryyb, jbeyq!
Cool, ça marche. Maintenant, nous voulons que ce script s’exécute à tout moment, qu’il soit redémarré en cas d’échec (sortie inattendue), et même qu’il survive aux redémarrages du serveur. C’est là que systemd entre en jeu.
Le transformer en service
Créons un fichier appelé /etc/systemd/system/rot13.service
:
Description=ROT13 demo service
After=network.target
StartLimitIntervalSec=0
Type=simple
Restart=always
RestartSec=1
User=centos
ExecStart=/usr/bin/env php /path/to/server.php
WantedBy=multi-user.target
Vous devrez :
- définir votre nom d’utilisateur réel après
User=
- définir le chemin d’accès approprié à votre script dans
ExecStart=
C’est tout. Nous pouvons maintenant démarrer le service :
$ systemctl start rot13
Et le faire démarrer automatiquement au démarrage :
$ systemctl enable rot13
Aller plus loin
Maintenant que votre service fonctionne (espérons-le), il peut être important de plonger un peu plus profondément dans les options de configuration, et de s’assurer qu’il fonctionnera toujours comme vous l’attendez.
Démarrer dans le bon ordre
Vous vous êtes peut-être demandé ce que faisait la directive After=
. Elle signifie simplement que votre service doit être lancé après que le réseau soit prêt. Si votre programme s’attend à ce que le serveur MySQL soit prêt à fonctionner, vous devriez ajouter :
After=mysqld.service
Démarrage à la sortie
Par défaut, systemd ne redémarre pas votre service si le programme quitte pour une raison quelconque. Ce n’est généralement pas ce que vous voulez pour un service qui doit être toujours disponible, nous lui demandons donc de toujours redémarrer à la sortie :
Restart=always
Vous pourriez également utiliser on-failure
pour ne redémarrer que si l’état de sortie n’est pas 0
.
Par défaut, systemd tente un redémarrage après 100 ms. Vous pouvez spécifier le nombre de secondes à attendre avant de tenter un redémarrage, en utilisant :
RestartSec=1
Éviter le piège : la limite de démarrage
Je suis personnellement tombé dans celui-ci plus d’une fois. Par défaut, lorsque vous configurez Restart=always
comme nous l’avons fait, systemd renonce à redémarrer votre service s’il échoue à démarrer plus de 5 fois dans un intervalle de 10 secondes. Pour toujours.
Il y a deux
options de configuration responsables de cela :
StartLimitBurst=5
StartLimitIntervalSec=10
La directive RestartSec
a également un impact sur le résultat : si vous la configurez pour qu’elle redémarre après 3 secondes, alors vous ne pourrez jamais atteindre 5 tentatives échouées en 10 secondes.
Le correctif simple qui fonctionne toujours est de définir StartLimitIntervalSec=0
. De cette façon, systemd tentera de redémarrer votre service pour toujours.
C’est une bonne idée de définir RestartSec
à au moins 1 seconde cependant, pour éviter de mettre trop de stress sur votre serveur lorsque les choses commencent à aller mal.
En guise d’alternative, vous pouvez laisser les paramètres par défaut et demander à systemd de redémarrer votre serveur si la limite de démarrage est atteinte, en utilisant StartLimitAction=reboot
.
C’est vraiment tout ?