EQVPS
DasborMulai

Cara menjadwalkan tugas di VPS dengan cron dan timer systemd

Jalankan backup, pembersihan, dan skrip sesuai jadwal. Cron dalam lima menit dengan tiga jebakan yang diam-diam merusak tugas, lalu timer systemd untuk log, mengejar jadwal setelah server mati, dan waktu yang tepat. Setiap perilaku di bawah diuji di server Ubuntu 24.04 baru.

Server membayar dirinya dengan bekerja saat Anda tidur: backup, rotasi log, perpanjangan sertifikat, laporan pukul sembilan. Linux punya dua penjadwal untuk itu. Cron berumur empat puluh tahun dan cukup satu baris. Timer systemd butuh dua file kecil, tetapi memberi log, mengejar jadwal setelah server mati, dan waktu yang tepat. Panduan ini membahas keduanya di Ubuntu 24.04, dengan setiap perilaku diperiksa di server baru dari image kami, termasuk tiga kesalahan yang membuat tugas cron gagal tanpa pesan apa pun.

Anda perlu pengguna dengan sudo; panduan penyiapan Ubuntu membuatnya.

1. Cron dalam lima menit

Cron sudah terpasang dan berjalan di image Ubuntu dan Debian kami. Setiap pengguna punya tabel tugas; sunting milik Anda dengan:

crontab -e

Setiap baris berisi lima kolom waktu dan satu perintah:

# min hour day month weekday  command
  30  3    *   *     *        /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
  */5 *    *   *     *        /usr/local/bin/check.sh
  0   9    *   *     1-5      /usr/local/bin/report.sh
  @reboot                     /usr/local/bin/start-tunnel.sh

Artinya: pukul 03:30 setiap malam, setiap 5 menit, pukul 09:00 di hari kerja, dan sekali setelah setiap boot. */5 berarti setiap nilai kelima, 1-5 rentang, 1,15 daftar. Zona waktu server berlaku, UTC di image kami; atur milik Anda sekali dengan panduan hostname dan zona waktu dan cron mengikutinya.

Periksa apa yang sudah berjalan dengan journalctl -u cron. Setiap eksekusi mencatat pengguna dan perintah, dan di situlah tiga jebakan terlihat.

Jebakan 1: output hilang. Cron mengirim output tugas ke pengguna lewat email. Image kami tidak punya server email, jadi journal menulis (CRON) info (No MTA installed, discarding output) dan outputnya hilang. Alihkan sendiri, seperti contoh pertama dengan >> /var/log/backup.log 2>&1.

Jebakan 2: tanda persen. Di crontab, % mengakhiri perintah dan mengubah sisanya menjadi input standar. Kami menjadwalkan date +%F > /tmp/today. Journal menunjukkan apa yang benar-benar dijalankan cron: CMD (date +). Tidak ada file yang ditulis dan tidak ada error yang sampai ke kami. Tulis \%, atau masukkan perintah ke skrip lalu jadwalkan skripnya.

Jebakan 3: lingkungan yang berbeda. Cron menjalankan tugas dengan /bin/sh, bukan bash, di direktori home Anda dan dengan lingkungan minim. Di Ubuntu 24.04 PATH-nya lebih baik dari reputasinya: path sistem lengkap termasuk /usr/local/bin dan /snap/bin, untuk root maupun pengguna biasa. Yang tetap tidak ada adalah semua yang berada di bawah home Anda: ~/.local/bin, node dari nvm, pipx, cargo. Gunakan path lengkap di tugas atau awali baris dengan . $HOME/.profile;.

Tugas milik sistem, bukan pengguna, diletakkan di /etc/cron.d/ sebagai file dengan satu kolom tambahan, yaitu pengguna:

30 3 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Ubuntu juga menjalankan semua yang ada di /etc/cron.hourly, cron.daily, cron.weekly, dan cron.monthly, pada menit ke-17 setiap jam, pukul 06:25, pukul 06:47 hari Minggu, dan pukul 06:52 setiap tanggal 1. Taruh skrip yang bisa dieksekusi di sana dan ia berjalan bersama yang lain.

2. Timer systemd

Sebuah timer terdiri dari dua unit: service yang mengerjakan tugas dan timer yang menentukan kapan. Buat skripnya dulu, lalu unitnya.

sudo nano /usr/local/bin/backup.sh
sudo chmod +x /usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Run the backup every night at 03:30

[Timer]
OnCalendar=*-*-* 03:30
Persistent=true
AccuracySec=1m

[Install]
WantedBy=timers.target

Aktifkan timernya, bukan service-nya:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer

list-timers menampilkan eksekusi berikutnya, sisa waktunya, dan eksekusi terakhir. Log tidak perlu disiapkan: journalctl -u backup.service berisi setiap mulai, selesai, dan baris output beserta waktunya. Untuk menjalankan tugas sekarang juga, sudo systemctl start backup.service; begitu pula cara menguji skrip sebelum memercayai jadwal.

Sintaks kalender. OnCalendar dibaca harimingguan tahun-bulan-hari jam:menit:detik, dengan * untuk nilai apa saja. Uji ekspresi sebelum dipakai:

systemd-analyze calendar "Mon..Fri *-*-* 03:00" --iterations 2

Perintah itu mencetak bentuk ternormalisasi dan tanggal berikutnya. Beberapa ekspresi yang kami periksa:

OnCalendarArti
*-*-* 03:30Setiap hari pukul 03:30
Mon..Fri *-*-* 09:00Hari kerja pukul 09:00
*:0/15Setiap 15 menit
weeklySenin pukul 00:00
*-*-01 04:00Tanggal 1 setiap bulan pukul 04:00
*-*-* 03:00 Europe/Kyiv03:00 waktu Kyiv; berjalan pukul 01:00 UTC di uji kami

Tiga pengaturan yang perlu diketahui. Persistent=true menyimpan eksekusi terakhir di disk dan mengejar eksekusi yang terlewat saat server mati atau timer dihentikan. Kami menghentikan timer dua menitan kami, menunggu satu jadwal lewat, lalu menyalakannya lagi: eksekusi yang terlewat berjalan pada detik yang sama. Tanpa Persistent, timer hanya menunggu slot berikutnya.

AccuracySec adalah kejutannya. Secara bawaan systemd mengelompokkan timer dalam jendela satu menit untuk menghemat bangun sistem, jadi eksekusi pertama kami datang pukul 07:42:18, bukan 07:42:00. Dengan AccuracySec=1s eksekusi berikutnya jatuh tepat pada detiknya, 07:46:00 dan 07:48:00. Atur saat menit penting; biarkan bawaan untuk backup malam.

RandomizedDelaySec=10m sengaja melakukan kebalikannya: menyebar waktu mulai dalam satu jendela agar sepuluh server tidak menghantam penyimpanan backup yang sama pada detik yang sama.

Untuk tugas sekali jalan, tidak perlu file sama sekali:

sudo systemd-run --on-active=30m --unit=cleanup-once /usr/local/bin/cleanup.sh

Perintah ini membuat timer sementara yang berjalan sekali lalu hilang; sampai saat itu systemctl list-timers menampilkannya.

3. Mana yang dipakai

CronTimer systemd
Penyiapan1 baris2 file
LogHanya jika output dialihkanjournalctl -u name.service
Eksekusi terlewat saat server matiHilangBerjalan saat boot dengan Persistent=true
Tugas masih berjalan saat jadwal berikutnyaSalinan kedua dimulaiDilewati sampai yang pertama selesai
Waktu tepatSampai menitSampai detik dengan AccuracySec=1s
StatusTidak adalist-timers, systemctl status

Pakai cron untuk satu baris cepat yang masih Anda kenali setahun lagi. Pakai timer untuk apa pun yang kegagalannya perlu Anda lihat, yang tidak boleh tumpang tindih, atau yang tetap harus berjalan setelah reboot yang terlewat: backup, perpanjangan sertifikat, pembersihan database. Jika tugas cron bisa tumpang tindih, bungkus: flock -n /tmp/backup.lock /usr/local/bin/backup.sh, dan salinan kedua langsung keluar.

Kedua penjadwal menjalankan tugas lalu berhenti. Untuk program yang harus berjalan terus dan hidup lagi setelah crash, Anda butuh service, bukan jadwal; lihat cara membuat service systemd dan untuk Windows cara menjalankan skrip 24/7 di Windows Server. Timer pertama yang bagus adalah dari panduan backup dengan restic kami; pembaruan keamanan otomatis adalah timer yang sudah dibawa Ubuntu, apt-daily-upgrade.timer, salah satu dari 17 yang berjalan di server baru.

FAQ

Kenapa tugas saya jalan di terminal tapi tidak di cron?

Tiga alasan umum. Cron menjalankan tugas dengan sh, bukan bash, jadi sintaks khusus bash gagal. Alat yang terpasang di direktori home Anda, seperti nvm, pipx, atau cargo, tidak ada di PATH cron, jadi gunakan path lengkap. Dan setiap % di baris perintah mengakhiri perintah: date +%F menjadi date + di server kami. Tulis sebagai \% atau pindahkan perintah ke skrip.

Ke mana output cron pergi?

Ke email, secara bawaan. Image kami tidak punya server email, jadi cron mencatat 'No MTA installed, discarding output' dan outputnya hilang. Tambahkan >> /var/log/myjob.log 2>&1 ke tugas, atau beralih ke timer systemd yang outputnya otomatis masuk ke journal.

Apa kelebihan timer systemd dibanding cron?

Log di journalctl, tidak ada salinan kedua dari tugas yang masih berjalan, Persistent=true mengejar jadwal yang terlewat saat server mati, dan baris status yang menunjukkan jadwal berikutnya serta terakhir. Cron unggul dalam ringkas: satu baris, bukan dua file.

Timer saya terlambat 18 detik. Kenapa?

Secara bawaan systemd mengelompokkan timer dalam jendela satu menit untuk menghemat bangun sistem, yaitu pengaturan AccuracySec. Timer dua menitan kami berjalan pukul 07:42:18, bukan 07:42:00. Dengan AccuracySec=1s ia berjalan tepat 07:46:00. Atur ini jika menit yang tepat penting.

Zona waktu apa yang dipakai cron dan timer?

Zona waktu server, yaitu UTC di image kami. Atur sekali dengan timedatectl, lihat panduan hostname dan zona waktu kami, maka cron dan timer mengikutinya. Timer juga bisa membawa zonanya sendiri: OnCalendar=*-*-* 03:00 Europe/Kyiv berjalan pukul 01:00 UTC dalam uji kami.

Komentar

Belum ada komentar. Jadilah yang pertama.

Tinggalkan komentar

Komentar dimoderasi sebelum muncul.