Systemd Timer vs Cron: Menjadwalkan Tugas Server dengan Benar
Masalah yang Sering Tidak Disadari dari Cron
Hampir semua tutorial VPS menyuruh Anda menulis jadwal di crontab -e. Itu tidak salah, tapi cron punya tiga kelemahan yang baru terasa saat ada masalah:
- Tidak ada log bawaan. Kalau job gagal, cron tidak memberi tahu Anda kecuali Anda mengarahkan outputnya sendiri atau mengandalkan email lokal yang sering tidak terkonfigurasi.
- Tidak ada retry. Kalau server mati tepat di jam jadwal, job itu lewat begitu saja. Tidak ada yang mengejarnya saat server hidup lagi.
- Lingkungan minimal. Cron menjalankan job dengan
PATHdan variabel lingkungan yang sangat terbatas. Script yang jalan mulus di terminal interaktif bisa gagal di cron karena perintah tidak ditemukan.
Contoh crontab yang umum:
# Backup database setiap hari jam 02:00 0 2 * * * /usr/local/bin/backup-db.sh >> /var/log/backup-db.log 2>&1
Lima kolom di depan adalah menit, jam, tanggal, bulan, dan hari dalam seminggu. Baris di atas berarti: menit ke-0, jam ke-2, setiap tanggal, setiap bulan, setiap hari. Bagian >> /var/log/backup-db.log 2>&1 wajib ada kalau Anda mau tahu apa yang terjadi — tanpa itu, output job hilang begitu saja.
Untuk job sistem (bukan milik satu user), Anda juga bisa menaruh file di /etc/cron.d/, dengan satu kolom tambahan berisi nama user:
# /etc/cron.d/backup-db 0 2 * * * root /usr/local/bin/backup-db.sh >> /var/log/backup-db.log 2>&1
Pastikan paket cron terpasang dan servicenya berjalan:
sudo apt install cron sudo systemctl enable --now cron sudo systemctl status cron
Systemd Timer: Jadwal dengan Log dan Retry
Systemd timer terdiri dari dua file yang selalu berpasangan: satu unit .service yang berisi perintahnya, dan satu unit .timer yang berisi jadwalnya. Keduanya ditaruh di /etc/systemd/system/ dan namanya harus sama, misalnya backup-db.service dan backup-db.timer.
Isi service-nya:
# /etc/systemd/system/backup-db.service [Unit] Description=Backup database harian After=network-online.target Wants=network-online.target [Service] Type=oneshot ExecStart=/usr/local/bin/backup-db.sh
Type=oneshot artinya service ini berjalan sekali lalu selesai, bukan daemon yang terus hidup. Bagian After= dan Wants= memastikan backup baru jalan setelah jaringan benar-benar siap — sesuatu yang tidak bisa dilakukan cron.
Isi timer-nya:
# /etc/systemd/system/backup-db.timer [Unit] Description=Jadwal backup database harian [Timer] OnCalendar=*-*-* 02:00:00 Persistent=true RandomizedDelaySec=15min [Install] WantedBy=timers.target
Penjelasan tiga baris penting di [Timer]:
- OnCalendar=*-*-* 02:00:00 berarti setiap hari jam 02:00. Formatnya mirip cron tapi lebih eksplisit: tahun-bulan-tanggal, lalu jam.
- Persistent=true adalah jawaban atas kelemahan cron nomor dua: kalau server mati saat jadwal tiba, timer akan langsung mengejar job yang tertinggal begitu server hidup lagi.
- RandomizedDelaySec=15min mengacak waktu eksekusi dalam rentang 15 menit. Berguna kalau Anda punya banyak server yang tidak boleh menghantam satu tujuan (misalnya server backup) di detik yang sama.
Setelah kedua file dibuat, aktifkan timernya:
sudo systemctl daemon-reload sudo systemctl enable --now backup-db.timer
Perintah daemon-reload wajib dijalankan setiap kali Anda mengubah file unit, kalau tidak systemd tetap memakai versi lama. Perhatikan juga: yang di-enable adalah timernya, bukan servicenya. Service akan dipicu otomatis oleh timer.
Memeriksa Jadwal dan Log
Di sinilah systemd timer terasa jauh lebih nyaman. Untuk melihat semua timer yang aktif dan kapan masing-masing berikutnya jalan:
systemctl list-timers --all
Kolom NEXT menunjukkan jadwal berikutnya, LAST menunjukkan eksekusi terakhir, dan LEFT menunjukkan sisa waktunya. Kalau ada timer yang tidak jalan, satu perintah ini langsung menunjukkannya.
Untuk log, tidak perlu lagi mengarahkan output ke file manual. Semua output service tercatat di jurnal systemd:
# Log eksekusi terakhir service backup journalctl -u backup-db.service # Log hari ini saja, dan ikuti secara live journalctl -u backup-db.service --since today -f
Kalau script gagal, Anda bisa melihat persis baris mana yang error dan kapan, tanpa menebak-nebak. Untuk cron, padanannya adalah membuka file log yang Anda arahkan sendiri — kalau Anda lupa mengarahkannya, tidak ada yang bisa dilihat.
Timer Selain Jadwal Kalender
OnCalendar bukan satu-satunya pemicu. Dua yang paling berguna di server:
[Timer] # Jalan 10 menit setelah boot, lalu setiap 6 jam setelah eksekusi terakhir selesai OnBootSec=10min OnUnitActiveSec=6h
OnBootSec cocok untuk tugas pembersihan atau pengecekan kesehatan yang harus jalan tak lama setelah server hidup. OnUnitActiveSec menghitung dari terakhir kali service aktif, sehingga intervalnya stabil meski eksekusi sebelumnya tertunda. Ada juga OnUnitInactiveSec yang menghitung dari terakhir kali service berhenti — bedanya tipis, tapi penting untuk job yang durasinya bervariasi.
Untuk menguji jadwal OnCalendar sebelum menunggu berhari-hari, gunakan:
systemd-analyze calendar "*-*-* 02:00:00"
Perintah ini menampilkan beberapa jadwal berikutnya yang dihasilkan dari ekspresi tersebut. Kalau hasilnya bukan yang Anda maksud, Anda tahu sebelum timer dipasang.
Kapan Pakai Cron, Kapan Pakai Systemd Timer
Pakai cron kalau jobnya sederhana, tidak kritis, dan Anda sudah nyaman dengan crontab. Contoh yang pas: menghapus file sementara seminggu sekali, atau menjalankan script kecil yang sudah terbukti stabil bertahun-tahun. Cron juga lebih mudah dijelaskan ke orang lain dalam satu baris.
Pakai systemd timer kalau salah satu dari ini berlaku:
- Job tidak boleh terlewat saat server sempat mati (Persistent=true).
- Anda butuh log yang bisa ditelusuri tanpa konfigurasi tambahan.
- Job bergantung pada kondisi tertentu, misalnya jaringan sudah siap atau service lain sudah jalan.
- Anda ingin retry otomatis saat gagal (Restart=on-failure dan RestartSec= bisa ditambahkan di [Service]).
- Jadwalnya bukan sekadar kalender, misalnya "10 menit setelah boot".
Satu catatan praktis: jangan mencampur keduanya untuk job yang sama. Cron dan timer yang sama-sama memanggil script yang sama adalah sumber klasik job ganda — backup jalan dua kali, notifikasi terkirim dua kali, dan Anda baru sadar setelah datanya berantakan.
Checklist Penutup
- Job sederhana dan tidak kritis? Cron satu baris sudah cukup — tapi selalu arahkan output ke file log.
- Job tidak boleh terlewat? Pakai systemd timer dengan Persistent=true.
- Habis membuat atau mengubah unit? Jalankan systemctl daemon-reload, lalu enable --now pada timernya.
- Timer sudah jalan? Verifikasi dengan systemctl list-timers --all, bukan dengan menunggu besok pagi.
- Ada yang gagal? Lihat journalctl -u <nama>.service sebelum menebak-nebak penyebabnya.
- Satu job, satu penjadwal. Jangan daftarkan script yang sama di cron dan timer sekaligus.
Komentar
Posting Komentar