Définissez une seule unité de travail finie
Imaginez un outil personnel qui reconstruit un petit résumé quotidien à partir de ses enregistrements existants. La tâche lit un ensemble borné de données, prépare un résumé de remplacement et se termine. Ce n'est pas un serveur web et il ne doit pas continuer à s'exécuter entre les démarrages planifiés. Notez l'entrée, la destination, la durée attendue et ce qui compte comme un succès avant d'ajouter un minuteur.
L'exemple suppose un hôte Linux avec systemd et util-linux flock, un accès administrateur, et un compte et un groupe non privilégiés existants nommés fieldjob. Son script de tâche révisé se trouve à /opt/field-jobs/build-summary et s'exécute au premier plan. Un administrateur possède ce script ; le compte de tâche peut le lire et l'exécuter mais ne peut pas réécrire son code. Vérifiez les chemins exécutables sur votre distribution. Ce sont des modèles, pas un service de planification OffVPS installé.
Le script doit signaler un échec avec un statut de sortie non nul. Pour les fichiers de remplacement, concevez-le pour préparer et vérifier un résultat temporaire avant de le publier. Pour le travail sur base de données, utilisez le mécanisme de transaction ou de déduplication de la base de données. Un verrou seul ne peut pas rendre une tâche partiellement terminée sûre à répéter.
Choisissez un fuseau horaire et une politique d'exécution manquée
Notre résumé est utile une fois par jour à 02:15 UTC. Utilisez une zone explicite pour que le fuseau horaire local de la machine ne soit pas une dépendance invisible. UTC évite les changements d'heure saisonniers dans cet exemple ; une tâche métier liée à l'heure civile locale a besoin d'un fuseau horaire nommé et d'un examen de son comportement à l'heure d'été. La référence temporelle systemd décrit les expressions calendaires.
Enregistrez ce modèle sous /etc/systemd/system/field-summary.timer sur le VPS prévu après avoir vérifié les noms :
[Unit]
Description=Daily personal-tool summary
[Timer]
OnCalendar=*-*-* 02:15:00 UTC
Persistent=true
Unit=field-summary.service
[Install]
WantedBy=timers.target
Persistent=true demande une activation de rattrapage après une période inactive si un événement calendaire a été manqué. Il ne rejoue pas une exécution séparée pour chaque jour manqué. Un minuteur ne démarre pas non plus une autre instance du même service tant que ce service est actif. Ces comportements, et la précision de la planification, sont couverts par la référence du minuteur. Décidez si un résumé tardif est utile avant d'activer le rattrapage.
Définissez l'utilisateur du service, le répertoire d'état et le verrou
Le /etc/systemd/system/field-summary.service correspondant décrit le travail :
[Unit]
Description=Build the personal-tool summary
[Service]
Type=oneshot
User=fieldjob
Group=fieldjob
WorkingDirectory=/opt/field-jobs
StateDirectory=field-summary
StateDirectoryMode=0700
UMask=0077
ExecStart=/usr/bin/flock --nonblock --conflict-exit-code 75 /var/lib/field-summary/job.lock /opt/field-jobs/build-summary
TimeoutStartSec=5min
StandardOutput=journal
StandardError=journal
Type=oneshot convient à une commande qui se termine ; un délai d'expiration explicite au démarrage borne cet exemple. N'ajoutez pas RemainAfterExit=yes à un service qui doit devenir inactif après chaque exécution. Voir la sémantique des services systemd. Définissez un délai d'expiration à partir de la charge de travail, et rendez l'interruption sûre plutôt que de supposer que cinq minutes conviennent à chaque tâche.
Pour ce service système, StateDirectory crée le répertoire nommé sous /var/lib avec la propriété du service. Le répertoire de travail, l'utilisateur, les permissions et les destinations de sortie sont explicites ; le script doit utiliser des chemins absolus pour ses propres outils et données. Les règles d'environnement et de répertoire sont documentées dans la référence d'exécution systemd. Ne mettez pas de valeurs secrètes dans les arguments de ligne de commande et ne les journalisez pas.
Le flock non bloquant se termine avec le code 75 lorsqu'une autre invocation coopérante détient ce verrou. Nous laissons délibérément cela comme un échec visible nécessitant un examen, plutôt que de traiter un résumé ignoré comme un travail terminé. Toutes les invocations manuelles doivent utiliser le même wrapper et le même chemin de verrou. Ne supprimez pas un fichier de verrou pour libérer une tâche en cours : un nouveau fichier peut créer un verrou séparé. C'est un modèle de système de fichiers local, pas un verrou distribué entre instances VPS. Voir le manuel upstream flock.
Vérifiez les fichiers, puis essayez une exécution contrôlée
Utilisez un jeu de données jetable avec le courrier sortant, les paiements et autres effets de bord désactivés pour la première exécution. Avant l'activation, inspectez la planification analysée et les fichiers d'unité sur cet hôte de test :
systemd-analyze calendar '*-*-* 02:15:00 UTC'
systemd-analyze verify /etc/systemd/system/field-summary.service /etc/systemd/system/field-summary.timer
Ces vérifications peuvent détecter des erreurs d'unité et de planification ; elles ne peuvent pas établir que votre script produit un résumé correct. La référence systemd-analyze explique leur portée. Après avoir corrigé les erreurs, chargez les fichiers révisés et démarrez explicitement la tâche de test :
sudo systemctl daemon-reload &&
sudo systemctl start field-summary.service
systemctl status field-summary.service --no-pager
sudo journalctl -u field-summary.service --since "10 minutes ago" --no-pager
Attendez-vous à une invocation réussie avec un résultat fini et un artefact de sortie vérifié ; un oneshot réussi peut apparaître inactif par la suite. Inspectez le résultat lui-même, y compris le comportement avec une entrée vide. Rendez une exécution de test délibérément lente, invoquez deux fois la même commande verrouillée sur le jeu de données de test, et vérifiez que la seconde invocation signale une contention de verrou sans écrire de résultat concurrent.
Activez la planification seulement après avoir vérifié sa sortie
sudo systemctl enable --now field-summary.timer
systemctl list-timers field-summary.timer --all
Vérifiez la prochaine heure planifiée, puis examinez le premier résultat planifié. Consignez l'heure de début, l'heure de fin, le nombre d'éléments traités et le résultat dans les journaux du script. L'absence d'enregistrement de succès est une raison d'inspecter, pas une preuve que la tâche a été exécutée. Reportez-vous à les commandes de minuteur et d'activation de systemctl.
Pour suspendre les démarrages futurs, utilisez sudo systemctl disable --now field-summary.timer. Cela ne termine pas un service déjà en cours d'exécution. Si une interruption est nécessaire, déterminez d'abord si son écriture actuelle peut s'arrêter en toute sécurité. À mesure que la charge augmente, examinez la durée, les tentatives et les limites des API externes ; plusieurs machines nécessitent une coordination partagée. Poursuivez avec le scénario d'outils personnels et un exercice de restauration pour les données que cette automatisation maintient.
Documentation utilisée
Références principales pour cette page. Consultez la documentation de la version installée dans votre propre environnement.