Generator dan Pembaca Ekspresi Cron
*/15minute*hour*day of month*month*day of weekJadwal berikutnya
waktu lokal AndaApa pun yang Anda masukkan di sini tidak disimpan, dicatat, atau dibagikan.
Tulis sebuah ekspresi cron dan lihat kapan saja ia benar-benar akan berjalan berikutnya. Setiap kolom divalidasi, dan jadwal yang tidak mungkin terpicu akan ditandai.
Cara memakai
- Ketik sebuah ekspresi, atau pilih praatur sebagai titik awal.
- Kelima kolomnya diberi label di bawah supaya Anda tahu mana yang mana.
- Periksa jadwal berikutnya sebelum Anda menerapkannya.
Lima field
Ekspresi cron standar terdiri dari lima field yang dipisahkan spasi: menit 0-59, jam 0-23, tanggal 1-31, bulan 1-12, dan hari dalam minggu 0-7, dengan 0 dan 7 sama-sama berarti Minggu. Bulan dan hari bisa ditulis dengan nama tiga huruf dalam bahasa Inggris.
Setiap field menerima empat bentuk yang sama. Tanda bintang cocok dengan semua nilai. Daftar yang dipisahkan koma cocok dengan salah satunya. Rentang dengan tanda hubung cocok dengan semua nilai di antaranya. Langkah dengan garis miring mengambil setiap nilai ke-n dari rentang, sehingga */15 di field menit berarti setiap seperempat jam dan 0-30/10 berarti menit 0, 10, 20, dan 30.
Singkatan @hourly, @daily, @weekly, @monthly, dan @yearly diperluas menjadi ekspresi yang sudah jelas dan layak dipakai jika sesuai, karena tidak mungkin salah dibaca.
Aturan tanggal dan hari
Inilah satu perilaku cron yang menjebak hampir semua orang, dan ini memang ditetapkan spesifikasi, bukan kebetulan. Jika field tanggal dan field hari sama-sama dibatasi - tidak satu pun berupa bintang - keduanya digabung dengan OR, bukan AND.
Jadi 0 0 1 * MON tidak berarti tanggal 1 yang jatuh pada hari Senin. Artinya tanggal 1 setiap bulan, dan juga setiap hari Senin. Jika Anda hanya ingin hari Senin, field tanggal harus berupa bintang. Jika hanya ingin tanggal 1, field hari harus berupa bintang. Tidak ada cara standar untuk menyatakan irisannya dalam ekspresi lima field, dan solusi yang biasa dipakai adalah menjadwalkan gabungannya lalu memeriksa tanggal di dalam job itu sendiri.
Daftar waktu eksekusi berikutnya ada justru untuk menangkap kasus seperti ini. Membaca field memberi tahu apa yang Anda tulis; membaca tanggalnya memberi tahu apa yang akan terjadi.
Zona waktu dan daylight saving
Waktu eksekusi yang ditampilkan di sini memakai zona waktu browser Anda. Server yang benar-benar menjalankan job punya zona waktunya sendiri, sering kali UTC, dan selisih keduanya adalah penyebab umum job berjalan di jam yang salah. Periksa pengaturan server, atau field zona waktu penjadwal Anda, sebelum memercayai waktu yang tepat.
Daylight saving menambah masalah yang lebih tajam. Di zona yang menerapkannya, job yang dijadwalkan pukul 02.30 sama sekali tidak berjalan pada pagi hari saat jam dimajukan, karena waktu itu tidak ada, dan berjalan dua kali pada pagi hari saat jam dimundurkan. Untuk apa pun yang bermasalah jika terlewat atau berjalan ganda - penagihan, rekonsiliasi, pengiriman email - jadwalkan dalam UTC, atau di luar rentang pukul satu sampai tiga pagi saat pergantian terjadi. Indonesia sendiri tidak menerapkan daylight saving, tetapi server dan pengguna Anda mungkin berada di zona yang menerapkannya.
Implementasi yang berbeda juga tidak sepakat soal job yang terlewat saat mesin tidur atau mati. Ada yang melewatkannya, ada yang menjalankannya saat mesin bangun, dan ada yang menjalankan semua jadwal yang terlewat sekaligus.
Ekstensi yang akan Anda temui di tempat lain
Lima field adalah standarnya, dan itulah yang diterima cron di Linux, Kubernetes CronJob, dan sebagian besar penjadwal terkelola. Beberapa sistem yang banyak dipakai memperluasnya, dan ekspresi yang disalin di antara sistem-sistem itu tidak selalu bermakna sama.
Quartz, termasuk penjadwal Spring yang memakainya, menggunakan enam atau tujuh field dengan menambahkan detik di depan dan tahun opsional di belakang, sehingga ekspresi lima field yang ditempel di sana dibaca dengan semua field bergeser satu posisi dan berjalan di waktu yang salah alih-alih gagal. Quartz juga menambahkan L untuk terakhir, W untuk hari kerja terdekat, dan # untuk hari ke-n dalam bulan. Vixie cron, standar di Linux, menambahkan @reboot. AWS EventBridge memakai enam field dan mewajibkan tepat satu dari dua field hari berupa tanda tanya, bukan bintang.
Alat ini memvalidasi dan menjelaskan standar lima field. Jika penjadwal Anda salah satu dari yang disebut di atas, periksa dokumentasinya sebelum menganggap sebuah ekspresi bermakna sama di sana.
Lingkungan tempat cron job benar-benar berjalan
Lebih banyak job terjadwal yang gagal karena urusan lingkungan daripada karena urusan penjadwalan. Cron tidak memuat profil shell Anda, sehingga PATH-nya minimal - sering kali hanya /usr/bin dan /bin - dan perintah yang jalan mulus di terminal Anda malah gagal dengan command not found. Kebiasaan yang bisa diandalkan adalah memakai path absolut untuk interpreter dan skripnya, atau menetapkan PATH secara eksplisit di bagian atas crontab.
Direktori kerjanya adalah home milik pengguna, bukan direktori proyek, jadi path relatif akan mengarah ke tempat yang tidak Anda duga. Variabel lingkungan yang dipasang oleh login shell Anda tidak ada, termasuk semua isi .env yang biasanya dimuat lewat hook shell. Selain itu tanda persen punya arti khusus di dalam crontab: ia diubah menjadi baris baru, dan itulah sebabnya string format tanggal seperti %Y diam-diam merusak sebuah perintah kecuali di-escape.
Separuh masalah lainnya ada pada output. Apa pun yang ditulis job ke stdout atau stderr akan dikirim sebagai surel ke pemiliknya jika ada mail transfer agent, dan dibuang begitu saja jika tidak ada - begitulah job bisa gagal tanpa suara selama berbulan-bulan. Arahkan output ke berkas log yang benar-benar Anda baca, atau buat job melapor ke sistem pemantauan Anda baik saat berhasil maupun saat gagal.
Tumpang tindih, idempotensi, dan jadwal yang terlewat
Cron menjalankan job sesuai jadwal tanpa peduli apakah eksekusi sebelumnya sudah selesai. Job yang butuh lima menit dengan jadwal tiap lima menit pada akhirnya akan berjalan dua salinan sekaligus, lalu tiga, dan kegagalannya biasanya muncul sebagai pekerjaan ganda atau deadlock, bukan sebagai kesalahan penjadwalan. Kunci - flock di Linux, advisory lock di basis data, atau lease di penyimpanan bersama - adalah solusi bakunya, dan kunci itu perlu timeout agar satu eksekusi yang crash tidak memblokir semua eksekusi berikutnya.
Rancang setiap job agar menjalankannya dua kali tidak menimbulkan kerugian. Umumnya itu berarti mencatat apa yang sudah diproses alih-alih menganggap jadwal yang menentukannya: pilih baris yang belum ditangani, tandai, lalu biarkan eksekusi kedua tidak menemukan pekerjaan apa pun.
Kebalikannya adalah jadwal yang terlewat. Jika mesin sedang tidur atau prosesnya gagal, sebagian implementasi melewati kemunculan itu, sebagian menjalankannya terlambat, dan sebagian lagi menjalankan semua kemunculan yang terlewat sekaligus. Anacron ada justru untuk menangani mesin yang tidak menyala sepanjang waktu, dan penjadwal kontainer punya kebijakannya masing-masing yang layak dibaca sebelum Anda bergantung padanya.
Alternatif modern untuk crontab
Timer systemd menggantikan cron di sebagian besar distribusi Linux saat ini dan menawarkan hal-hal yang tidak pernah dimiliki cron: pengurutan berdasarkan dependensi, batas sumber daya, pencatatan otomatis ke journal, jeda acak untuk menghindari lonjakan serentak, dan Persistent=true supaya eksekusi yang terlewat dijalankan pada boot berikutnya. Biayanya adalah konfigurasi yang lebih banyak, karena satu timer dan satu unit service berarti dua berkas, bukan satu baris.
Kubernetes CronJob memakai sintaks lima kolom yang sama lalu menambahkan kebijakan konkurensi, batas riwayat, dan penanganan tenggat - persis rangkaian masalah yang dibahas di atas, kini dibuat eksplisit. Penjadwal terkelola seperti event bus di cloud, jadwal CI, dan timer serverless umumnya menjanjikan pengiriman minimal satu kali, bukan tepat satu kali, sehingga urusan idempotensi kembali jatuh ke pundak job itu sendiri.
Untuk pekerjaan di dalam sebuah aplikasi, antrean dengan pesan tertunda sering kali lebih cocok daripada penjadwal mana pun, karena percobaan ulang, visibilitas, dan pemantauan sudah menyatu dengan antrean alih-alih ditempelkan belakangan.
Jadwal yang benar-benar ditulis orang
Setiap lima belas menit adalah */15 * * * *. Setiap malam pukul 02:30 adalah 30 2 * * *. Hari kerja pukul 09:00 adalah 0 9 * * 1-5. Tanggal satu setiap bulan pada tengah malam adalah 0 0 1 * *, sedangkan untuk hari terakhir bulan tidak ada ekspresi baku sama sekali - akalan yang biasa dipakai adalah menjalankannya setiap hari lalu keluar kecuali besok adalah tanggal satu.
Ada dua kebiasaan yang membuat crontab tetap terbaca di kemudian hari. Sebarkan bebannya alih-alih menjadwalkan semuanya tepat di awal jam: 7 3 * * * sama mudahnya ditulis dengan 0 3 * * * tetapi menghindari rebutan dengan semua job lain di mesin itu. Lalu beri komentar di setiap baris tentang apa yang dikerjakannya dan siapa pemiliknya, karena crontab bertahan lebih lama daripada ingatan orang yang menambahkan baris itu.
Kalau sebuah jadwal memang rumit, memecahnya menjadi dua entri sederhana biasanya lebih jelas daripada satu ekspresi yang pintar - dan kejelasan itulah yang Anda butuhkan pada pukul tiga pagi, saat job yang setahun penuh berjalan tenang tiba-tiba berhenti.
Mengetahui apakah job benar-benar berjalan
Kegagalan khas pekerjaan terjadwal adalah kesunyian. Job yang gagal dengan ribut akan diperbaiki hari itu juga; job yang berhenti berjalan sama sekali tidak menghasilkan output, dan tidak ada yang sadar sampai laporan mingguan yang dibuatnya absen untuk minggu ketiga.
Pola yang menyelesaikannya adalah pemantauan dead man's switch: job mengirim ping ke layanan pemantauan ketika berhasil, dan layanan itu memberi peringatan bila ping tidak datang dalam rentang waktu yang diharapkan. Cara ini membalik arah peringatan yang biasa dan menangkap segalanya - host yang mati, crontab yang terhapus, deploy yang gagal, mesin yang tidak pernah kembali setelah reboot - karena dari luar semuanya tampak sama persis, yaitu tidak terjadi apa-apa.
Catat apa yang dikerjakan sebuah eksekusi, bukan sekadar bahwa ia terjadi. Satu baris berisi waktu mulai, waktu selesai, jumlah record yang diproses, dan status keluar mengubah kecurigaan samar menjadi jawaban, dan itulah beda antara tahu bahwa job berjalan dan tahu bahwa job bekerja. Ketika job malam diam-diam memproses nol baris selama sebulan, angka jumlah di log biasanya satu-satunya bukti kapan hal itu mulai terjadi.
Pertanyaan umum
- Kenapa menampilkan jadwal berikutnya alih-alih sekadar deskripsi?
- Karena sebuah ekspresi bisa saja sepenuhnya valid namun tetap tidak berarti seperti yang Anda maksudkan. Membaca lima kolom memberi tahu apa yang Anda tulis; melihat enam tanggal berikutnya memberi tahu apa yang akan terjadi. Di selisih itulah bug penjadwalan biasanya tertangkap.
- Apa yang terjadi kalau saya mengisi hari dalam bulan dan hari dalam minggu sekaligus?
- Keduanya digabungkan dengan ATAU, bukan DAN. Jadi "0 0 1 * MON" berjalan pada tanggal 1 setiap bulan DAN setiap hari Senin, bukan hanya Senin yang jatuh pada tanggal 1. Ini mengejutkan hampir semua orang, merupakan perilaku yang memang dispesifikasikan alih-alih keanehan, dan daftar jadwal berikutnya membuatnya langsung terlihat.
- Sintaks cron mana yang didukung?
- Cron standar lima kolom: menit, jam, hari dalam bulan, bulan, hari dalam minggu. Wildcard, rentang, daftar, langkah, serta nama bulan dan hari tiga huruf semuanya diterima, begitu pula pintasan @daily, @hourly, @weekly, @monthly, dan @yearly. Minggu boleh ditulis 0 atau 7.
- Jadwal yang ditampilkan memakai zona waktu apa?
- Zona waktu peramban Anda. Cron di server berjalan pada zona waktu server itu, yang sering kali UTC dan sering pula berbeda dari yang ditampilkan komputer Anda, jadi periksa pengaturan server sebelum mengandalkan jam yang persis.
- Kenapa ia bilang sebuah ekspresi tidak akan pernah berjalan?
- Sebagian kombinasi memang mustahil, seperti 30 Februari. Alih-alih menampilkan daftar kosong, alat ini menyatakannya langsung.
Terakhir diperbarui:
Sertakan langkah, hasil yang diharapkan, dan hasil sebenarnya. Hapus rahasia dan data pribadi.
