Arbeiten mit Timern in Systemd

Erläutert, wie systemd Timer-Einheiten die Arbeit planen und wie Echtzeit-, monotone und transiente Timer konfiguriert werden.

Timer Unit-Dateien sind ein Typ von systemd-Datei, mit dem das systemctl-Utility Aufgaben plant, ähnlich wie das cron-Utility, das crontab und andere cron-Jobs für denselben Zweck verwendet.

Beachten Sie, dass der Cron-Daemon als Service innerhalb von systemd ausgeführt wird. Daher werden Timereinheiten bevorzugt, da sie eine zusätzliche Verarbeitungsebene entfernen und viel mehr Utility und eine detailliertere Konfiguration bieten, als im Cron-Service verfügbar ist.

In der Regel enthalten Pakete, die bestimmte Services für die Funktion im System verwenden, ihre eigenen systemd-Timereinheitendateien. Wenn diese Packages also mit Oracle Linux installiert werden, werden die Timer Unit-Dateien automatisch eingeschlossen. Mit dem folgenden Befehl können Sie die Timer-Dateien auf dem System anzeigen:

systemctl list-unit-files --type=timer
Hinweis

Die Liste der Timerdateien kann je nach Ausführungsort von Oracle Linux variieren, z.B. in einer Instanz in Oracle Cloud Infrastructure, einem physischen System usw.

Jede Timer Unit-Datei enthält Parametereinstellungen, mit denen der Zeitplan einer Aufgabe verwaltet wird. Beispiel: Der Zeitplan für die Ausführung von dnf-makecache.service wird in der Datei dnf-makecache.timer festgelegt. Die Datei enthält die folgenden Einstellungen:

systemctl cat dnf-makecache.timer
# /usr/lib/systemd/system/dnf-makecache.timer
[Unit]
Description=dnf makecache --timer
ConditionKernelCommandLine=!rd.live.image
# See comment in dnf-makecache.service
ConditionPathExists=!/run/ostree-booted
Wants=network-online.target

[Timer]
OnBootSec=10min
OnUnitInactiveSec=1h
RandomizedDelaySec=60m
Unit=dnf-makecache.service

[Install]
WantedBy=timers.target

Die Zeitplaninformationen werden im Abschnitt [Timer] angegeben.

In der Beispielkonfiguration wird der dnf-makecache.service-Service 10 Minuten nach dem Booten des Systems automatisch ausgeführt. Der Service geht dann eine Stunde lang in den Leerlaufmodus, wie durch den Parameter OnUnitInactiveSec angegeben. Am Ende der Stunde wird der Service erneut ausgeführt. Dieser Zyklus wird jede Stunde auf unbestimmte Zeit fortgesetzt.

Die Einstellung RandomizedDelaySec gibt einen Grenzwert an, wie viel eine Ausführung über ihren Zeitplan hinaus verzögert werden kann.

In diesem Beispiel darf der Service spätestens eine Minute nach seinem Zeitplan ausgeführt werden. Dieser Parameter ist nützlich, um zu viele Jobs zu verhindern, die gleichzeitig mit einem angegebenen Zeitplan beginnen, was ansonsten zu einer Überlastung der Ressourcen führen würde.

OnCalendar ist ein weiterer nützlicher Parameter für die Aufgabenplanung. Angenommen, der Parameter ist wie folgt festgelegt:

OnCalendar=*:00/10

*:00 gibt jede Stunde am Anfang der Stunde an, während die Einstellung /10 10 Minuten angibt. Daher wird der Job stündlich ausgeführt, und zwar zehn Minuten nach dem Ende der Stunde.

Eine vollständige Liste der Parameter der systemd-Timereinheitendatei für die Planung eines Jobs finden Sie in den systemd.timer(5)-Manpages.

Tipp

Ein Tutorial zur Verwendung von systemd in Oracle Linux, einschließlich der Konfiguration von systemd-Timereinheitendateien, finden Sie unter https://docs.oracle.com/en/learn/ol-systemd/.

Laufzeit von Serviceeinheiten mit Timereinheiten steuern

Erläutert, wie Timereinheiten Cron-Jobs ersetzen und wie Timer-ausgelöste Services geprüft, aktiviert und überwacht werden.

Timereinheiten können so konfiguriert werden, dass sie steuern, wann Serviceeinheiten ausgeführt werden.

Sie können Timereinheiten verwenden, anstatt den cron-Daemon für zeitbasierte Ereignisse zu konfigurieren. Die Konfiguration von Timereinheiten kann komplizierter sein als die Erstellung eines crontab-Eintrags. Timereinheiten sind jedoch konfigurierbarer, und die von ihnen gesteuerten Services können für eine bessere Protokollierung und eine tiefere Integration mit der systemd-Architektur konfiguriert werden.

Timereinheiten werden ähnlich wie Serviceeinheiten gestartet, aktiviert und gestoppt. Beispiel: Um eine Timereinheit sofort zu aktivieren und zu starten, geben Sie Folgendes ein:

sudo systemctl enable --now myscript.timer

Um alle vorhandenen Timer im System aufzulisten, um zu sehen, wann sie zuletzt ausgeführt wurden und wann sie als Nächstes für die Ausführung konfiguriert werden, geben Sie Folgendes ein:

systemctl list-timers

Weitere Informationen zu Systemtimern finden Sie in den Handbuchseiten systemd.timer(5) und systemd.time(7).

Echtzeit-Timer-Einheit konfigurieren

Echtzeit-Timer werden bei einem Kalenderereignis aktiviert, ähnlich wie bei Ereignissen in einer Crontab. Die Option OnCalendar gibt an, wann der Timer einen Service ausführt.

  • Erstellen Sie bei Bedarf eine .service-Datei, die den Service definiert, der von der Timereinheit ausgelöst werden soll. Im folgenden Verfahren ist der Beispielservice /etc/systemd/system/update.service, eine Serviceeinheit, die ein Aktualisierungsskript ausführt.

    Weitere Informationen zum Erstellen von Serviceeinheiten finden Sie unter Erstellen eines benutzerbasierten systemd Service.

  • Festlegen von Uhrzeit und Häufigkeit für die Ausführung des Service. In diesem Verfahren ist der Timer so konfiguriert, dass der Service von Montag bis Freitag alle 2 Stunden ausgeführt wird.

In dieser Aufgabe wird gezeigt, wie Sie einen Systemtimer erstellen, um die Ausführung eines Service basierend auf einem Kalenderereignis auszulösen. Die Definition des Kalenderereignisses ähnelt den Einträgen, die Sie in einen Cron-Job eingeben.

  1. Erstellen Sie die /etc/systemd/system/update.timer mit dem folgenden Inhalt:
    [Unit]
    Description="Run the update.service every two hours from Mon to Fri."
    
    [Timer]
    OnCalendar=Mon..Fri 00/2 
    Unit=update.service
    
    [Install]
    WantedBy=multi-user.target

    OnCalendar kann eine einfache Einstellung wie OnCalendar=weekly verwenden oder komplexere Definitionen verwenden, die detaillierter sind. Das Format zum Definieren von Einstellungen ist jedoch wie folgt konstant:

    DayofWeek Year-Month-Day Hour:Minute:Second

    Die folgende Definition bedeutet "die ersten 4 Tage jedes Monats um 12:00 Uhr mittags, aber nur, wenn dieser Tag entweder ein Montag oder ein Dienstag ist":

    OnCalendar=Mon,Tue *-*-01..04 12:00:00

    Weitere Möglichkeiten zum Definieren von OnCalendar und weitere Timeroptionen, die Sie in der Systemtimerdatei konfigurieren können, finden Sie auf den Manpages systemd.timer(5) und systemd.time(7).

  2. Prüfen Sie, ob alle mit diesem Timer verbundenen Dateien korrekt konfiguriert sind.
    systemd-analyze verify /etc/systemd/system/update.*

    Alle erkannten Fehler werden auf dem Bildschirm gemeldet.

  3. Starten Sie den Timer.
    sudo systemctl start update.timer

    Mit diesem Befehl wird der Timer nur für die aktuelle Sitzung gestartet.

  4. Stellen Sie sicher, dass der Timer beim Booten des Systems gestartet wird.
    sudo systemctl enable update.timer

Monotonische Timer-Einheit konfigurieren

Monotonische Timer werden nach einer Zeitspanne relativ zu einem variierenden Startpunkt, wie z.B. einem Bootereignis, aktiviert oder wenn eine bestimmte systemd-Einheit aktiv wird. Diese Timer-Einheiten stoppen, wenn der Computer vorübergehend unterbrochen oder heruntergefahren wird. Monotonische Timer werden mit der Option OnTypeSec konfiguriert, wobei Type der Name des Ereignisses ist, auf das sich der Timer bezieht. Zu den gängigen monotonischen Timern gehören OnBootSec und OnUnitActiveSec.

  • Erstellen Sie bei Bedarf eine .service-Datei, die den Service definiert, der von der Timereinheit ausgelöst werden soll. Im folgenden Verfahren ist der Beispielservice /etc/systemd/system/update.service, eine Serviceeinheit, die ein Aktualisierungsskript ausführt.

    Weitere Informationen zum Erstellen von Serviceeinheiten finden Sie unter Erstellen eines benutzerbasierten systemd Service.

  • Festlegen von Uhrzeit und Häufigkeit für die Ausführung des Service. In diesem Verfahren ist der Timer so konfiguriert, dass der Service 10 Minuten nach dem Booten des Systems und alle 2 Stunden nach der letzten Aktivierung des Service ausgeführt wird.

In dieser Aufgabe wird gezeigt, wie Sie einen Systemtimer erstellen, um die Ausführung eines Service bei bestimmten Ereignissen auszulösen. Dies geschieht, wenn das System bootet oder nach 2 Stunden nach der Aktivierung des Timers abgelaufen ist.

  1. Erstellen Sie die /etc/systemd/system/update.timer mit dem folgenden Inhalt:
    [Unit]
    Description="Run the update.service every two hours from Mon to Fri."
    
    [Timer]
    OnBootSec=10min
    OnUnitActiveSec=2h
    Unit=update.service
    
    [Install]
    WantedBy=multi-user.target

    Weitere Timer-Optionen, die Sie im System-Timer konfigurieren können, finden Sie in den Handbuchseiten systemd.timer(5) und systemd.time(7).

  2. Prüfen Sie, ob alle mit diesem Timer verbundenen Dateien korrekt konfiguriert sind.
    systemd-analyze verify /etc/systemd/system/update.*

    Alle erkannten Fehler werden auf dem Bildschirm gemeldet.

  3. Starten Sie den Timer.
    sudo systemctl start update.timer

    Mit diesem Befehl wird der Timer nur für die aktuelle Sitzung gestartet.

  4. Stellen Sie sicher, dass der Timer beim Booten des Systems gestartet wird.
    sudo systemctl enable update.timer

Transiente Timer-Einheit ausführen

Zeigt, wie Sie einmalige Timer mit systemctl run starten, damit Sie Ad-hoc-Aufgaben planen können, ohne Unit-Dateien zu erstellen.

Transiente Timer sind temporäre Timer, die nur für die aktuelle Sitzung gültig sind.

Diese Timer können erstellt werden, um ein Programm oder Skript direkt auszuführen, ohne dass Service- oder Timereinheiten innerhalb von systemd konfiguriert werden müssen. Diese Einheiten werden mit dem Befehl systemd-run generiert. Weitere Informationen finden Sie im Handbuch systemd-run(1).

Die Parameteroptionen, die Sie der Datei unit-file.timer hinzufügen würden, dienen auch als Argumente, wenn Sie mit dem Befehl systemd-run eine transiente Timereinheit ausführen.

Die folgenden Beispiele zeigen, wie Sie mit systemd-run transiente Timer aktivieren.

  • Führen Sie update.service aus, nachdem 2 Stunden vergangen sind.

    sudo systemd-run --on-active="2h" --unit update.service
  • Erstellen Sie ~/tmp/myfile nach 1 Stunde.

    sudo systemd-run --on-active="1h" /bin/touch ~/tmp/myfile
  • Führen Sie ~/myscripts/update.sh 5 Minuten nach dem Starten des Servicemanagers aus. Verwenden Sie diese Syntax, um einen Service auszuführen, nachdem der Service Manager bei der Benutzeranmeldung gestartet wurde.

    sudo systemd-run --on-startup="5m" ~/myscripts/update.sh
  • Führen Sie myjob.service 10 Minuten nach dem Systemstart aus.

    sudo systemd-run --on-boot="10m" --unit myjob.service
  • Führen Sie report.service am Ende des Tages aus.

    sudo systemd-run --on-calendar="17:00:00"