linux-ubuntu-debian automation cron systemd scheduling maintenance

Task Scheduling: Cron vs. Systemd Timers (Artikel 053)

Vergleich klassischer Cron-Jobs mit modernen Systemd-Timern. Anleitung zur Migration, komplexe Zeitplanung und Überwachung von Hintergrundaufgaben.

# Task Scheduling Deep Dive: Cron vs. Systemd Timers

TL;DR / Management Summary Jedes Linux-System benötigt eine Methode, um Aufgaben zeitgesteuert auszuführen (Backups, Log-Rotation, Cleanup). Während Cron der 50 Jahre alte, robuste Standard ist, bieten Systemd-Timer massive Vorteile in Enterprise-Umgebungen: Besseres Logging via Journald, Abhängigkeiten von anderen Diensten (z.B. “Nur starten, wenn Netzwerk da ist”) und präzise Kontrolle über Ressourcen (CPU/RAM).


# 1. Einführung & Architektur

Alt vs. Neu.

  • Cron: Ein Dämon (crond), der jede Minute aufwacht und in /var/spool/cron/ nachsieht. Logs landen oft unsortiert im Syslog.
  • Systemd-Timer: Native Systemd-Objekte. Der Timer triggert ein Service-Unit. Volle Integration in den System-Status.

# Architektur-Vergleich (Mermaid)

graph TD
    subgraph "Cron Model"
        A[Crontab File] --> B[cron Daemon]
        B -->|Execute| C[Script / Binary]
        C -->|Output| D[Mailed to local root]
    end
    subgraph "Systemd Model"
        E[timer.unit] -->|Trigger| F[service.unit]
        F -->|Execute| G[Script / Binary]
        G -->|stdout/stderr| H[systemd-journald]
        H --> I[Centralized Monitoring]
    end

# 2. Cron: Der Klassiker

Schnell, aber blind.

# Syntax

* * * * * Befehl (Minute, Stunde, Tag, Monat, Wochentag)

# Best Practice für Admins

Nutzen Sie niemals crontab -e für produktive Systemaufgaben. Nutzen Sie stattdessen Dateien in /etc/cron.d/, da diese versionierbar sind.

# /etc/cron.d/backup
0 3 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# 3. Systemd-Timers: Der Enterprise-Weg

Sichtbarkeit und Kontrolle.

# Komplexe Zeitplanung (OnCalendar)

Systemd nutzt eine lesbarere Syntax als Cron.

Ausdruck Bedeutung
daily Jeden Tag um 00:00
Mon..Fri 03:00 Werktags um 3 Uhr morgens
*-*-1,15 04:00 Jeden 1. und 15. des Monats
hourly Jede volle Stunde

# Beispiel: Ein Timer mit Abhängigkeit

Triggert /etc/systemd/system/sync.service.

[Unit]
Description=Sync to Cloud Timer

[Timer]
OnCalendar=*-*-* 04:00:00
# Warte zufällig bis zu 30 Min (verhindert Load-Spikes im Cluster)
RandomizedDelaySec=30m
Persistent=true

[Install]
WantedBy=timers.target

# 4. Day-2 Operations: Monitoring

Hat der Job funktioniert?

# Cron-Jobs überwachen

Schwierig. Man muss /var/log/syslog greppen oder Mails an Root abfangen.

# Systemd-Timer überwachen

# Liste aller Timer und wann sie das nächste Mal laufen
systemctl list-timers

# Status des letzten Laufs
systemctl status sync.service

# Logs des Jobs
journalctl -u sync.service -e

# 5. Troubleshooting & “War Stories”

Praxisfallen.

# Story 1: “Der verpasste Job (Reboot)”

Symptom: Ein Cron-Job für 03:00 Uhr läuft nie, weil der Server nachts wegen Wartung aus war. Ursache: Cron hat kein Gedächtnis. Verpasste Zeiten werden nicht nachgeholt. Lösung: Systemd-Timer mit Persistent=true. Systemd merkt sich den letzten Lauf auf der Disk und holt den Job nach dem Booten sofort nach.

# Story 2: “Der überlappende Job”

Symptom: Ein Backup-Skript läuft 2 Stunden, wird aber jede Stunde gestartet. Nach 5 Stunden stürzt der Server wegen Load ab. Ursache: Cron startet den nächsten Prozess blind. Lösung: Systemd-Services verhindern dies nativ. Ein Service, der bereits läuft, wird vom Timer nicht noch einmal gestartet (solange er vom Typ simple oder oneshot ist).


# 6. Fazit & Empfehlung

  • Migration: Migrieren Sie geschäftskritische Jobs (Backups, DB-Wartung) zu Systemd-Timern.
  • Einfachheit: Nutzen Sie Cron nur für absolut triviale Einzeiler auf Standalone-Maschinen.
  • Monitoring: Integrieren Sie Systemd-Failed-Units in Ihr Monitoring (Zabbix/Prometheus), um sofort über fehlgeschlagene Timer informiert zu werden.

# Anhang: Cheatsheet

Aufgabe Cron Systemd Timer
Liste anzeigen crontab -l systemctl list-timers
Job manuell testen Befehl kopieren & ausführen systemctl start <service>
Sofort stoppen pkill <process> systemctl stop <service>
Logging /var/log/syslog journalctl -u <service>
Random Delay Nicht vorhanden RandomizedDelaySec=