systemd timer’lar: cron’ga muqobil
cron asoslari va crontab va tizim cron’i maqolalarida cron ko'rib chiqildi — o'nlab yillardan beri ishlatib kelinayotgan oddiy va ishonchli vosita. systemd allaqachon PID 1 sifatida ishlayotgan tizimda uning muqobili bor: systemd timer. U cron bilan bir xil ishni — buyruqni jadval bo'yicha ishga tushirishni — bajaradi, lekin buni journalctl, unit bog'liqliklari va resurs boshqaruvi bilan integratsiyalashgan systemd unit sifatida qiladi.
Bu maqola cron "noto'g'ri" ekanini isbotlash uchun yozilmagan. U ikkalasi o'rtasidagi amaliy farqlarni ko'rsatib beradi, shunda ular orasidan ongli tanlov qilish mumkin bo'ladi.
Nimalarni o'rganasiz
Bu maqola oxirida siz quyidagilarni qila olasiz:
- systemd timer ikkita fayldan —
.serviceva.timerdan — iborat ekanini tushuntirish; OnCalendar=yordamida cron’ga o'xshash jadval yozish;- cron ifodalay olmaydigan jadvallar uchun interval (monotonic) timer’lar —
OnBootSec=vaOnUnitActiveSec=— dan foydalanish; RandomizedDelaySec=vaAccuracySec=bilan serverlar parki yuklamasini taqsimlash va ishga tushish aniqligini boshqarish;- yangi timer’ni yoqish, uning holatini va keyingi ishga tushish vaqtini tekshirish;
- timer chiqishini
journalctlorqali ko'rish va hech qachon ishga tushmayotgan timer’ni diagnostika qilish; - qachon cron yaxshiroq tanlov, qachon systemd timer ekanini hal qilish.
Bitta qator o'rniga ikkita fayl
cron’da jadval va buyruq bitta qatorda birga yoziladi. systemd timer esa ikkita alohida unit fayldan iborat:
Bu ajratishning afzalligi: mytask.service ni jadvaldan mustaqil ravishda, istalgan vaqtda qo'lda ishga tushirish mumkin (systemctl start mytask.service). Bu sinov uchun yoki qo'lda qayta ishga tushirish uchun qulay.
Misol: har kuni log'larni tozalash
1. Service faylini yaratish
Type=oneshot systemd’ga bu unit doimiy ishlaydigan servis emas, balki bir marta ishga tushib tugaydigan vazifa ekanini aytadi. Bu turdagi unit odatda o'z-o'zidan ishga tushirilmaydi — u timer tomonidan ishga tushirilishi uchun mo'ljallangan.
2. Timer faylini yaratish
[Unit]
Description=Daily schedule for log-cleanup.service
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
OnCalendar=daily— har kuni soat 00:00 da bir marta ishga tushirish (daily—*-*-* 00:00:00ning qisqartmasi);Persistent=true— agar server o'chiq bo'lgan bo'lsa yoki timer’ning rejalashtirilgan vaqti biror sabab bilan o'tkazib yuborilgan bo'lsa, o'tkazib yuborilgan ishga tushirish tizim qayta yoqilishi bilanoq bajariladi (cron’da bunga teng xatti-harakat yo'q).
OnCalendar= cron ifodasiga qaraganda o'qilishi osonroq sintaksisdan foydalanadi:
| Maqsad | OnCalendar= qiymati |
Taxminiy cron ekvivalenti |
|---|---|---|
| Har kuni yarim tunda | daily yoki *-*-* 00:00:00 |
0 0 * * * |
| Har soatda | hourly |
0 * * * * |
| Har dushanba soat 03:00 da | Mon *-*-* 03:00:00 |
0 3 * * 1 |
| Har oyning 1-kuni soat 04:30 da | *-*-01 04:30:00 |
30 4 1 * * |
OnCalendar= ifodasini haqiqiy timer’ga ulashdan oldin tekshirib ko'rish mumkin:
Original form: Mon *-*-* 03:00:00
Normalized form: Mon *-*-* 03:00:00
Next elapse: Mon 2026-07-27 03:00:00 UTC
Next elapse ifoda haqiqatan mo'ljallangan vaqtga to'g'ri kelishini tasdiqlaydi. Buning uchun tizimni qayta yuklash yoki uning ishga tushishini kutish shart emas.
3. Timer’ni yoqish
--now timer’ni darhol faollashtiradi va tizim yuklanganda uning avtomatik ishga tushishini ham ta’minlaydi. Bu yerda nima yoqilayotganiga e’tibor bering — log-cleanup.service emas, log-cleanup.timer. Service’ni bevosita yoqish shart emas, uni timer ishga tushiradi.
Holatni tekshirish
NEXT LEFT LAST PASSED UNIT ACTIVATES
Sat 2026-07-25 00:00:00 UTC 13h left n/a n/a log-cleanup.timer log-cleanup.service
- NEXT/LEFT — keyingi rejalashtirilgan ishga tushirish va unga qancha vaqt qolgani;
- ACTIVATES — timer qaysi servisni ishga tushirishga sozlangani.
Bu systemd timer’larning cron’ga nisbatan aniq afzalligi: keyingi ishga tushish vaqtini crontab qatorini o'qib taxmin qilish yoki qayta yuklanishni kutish o'rniga to'g'ridan-to'g'ri tekshirish mumkin.
Chiqishni ko'rish: journalctl
cron’da chiqish odatda alohida sozlanishi kerak bo'lgan email yoki qo'lda tanlangan log fayl orqali kuzatiladi (cron muhiti va log'lari maqolasida ko'rib chiqilgan). systemd timer’da esa log-cleanup.service stdout yoki stderr ga yozgan hamma narsa hech qanday qo'shimcha sozlamasiz avtomatik ravishda journalctl ga tushadi.
Vazifa muvaffaqiyatli yoki xato bilan tugaganini bilish uchun:
Qo'lda ishga tushirish
Sinov uchun vazifani jadvalni kutmasdan darhol ishga tushirish:
Bu timer’ga umuman tegmaydi — u shunchaki servisni bir marta ishga tushiradi. Shunday qilib, jadvalni vaqtincha o'zgartirmasdan asosiy buyruqni sinab ko'rish mumkin.
Interval timer’lar: OnBootSec va OnUnitActiveSec
OnCalendar= vazifani xuddi cron kabi aniq soat vaqtlariga bog'laydi. systemd shuningdek kalendarga emas, biror hodisaga nisbatan ishga tushadigan monotonic timer’larni ham taklif qiladi:
OnBootSec=— mashina yuklangandan keyingi belgilangan kechikish, masalanOnBootSec=15min("har bir yuklanishdan 15 daqiqa keyin");OnUnitActiveSec=— servis oxirgi marta faollashtirilgan vaqtdan boshlab o'lchanadigan belgilangan interval, masalanOnUnitActiveSec=10s.
Birinchi ishga tushirishning aniq boshlanish nuqtasi bo'lishi uchun ikkalasi odatda birga ishlatiladi:
Bu "birinchi marta yuklanishdan bir daqiqa keyin, so'ng har 10 soniyada" degani. Bu jadvalning umuman cron ekvivalenti yo'q — cron faqat aniq soat vaqtlarini ifodalay oladi va uning eng kichik aniqligi bir daqiqa. Har 10 soniyada yoki "shu host yuklangandan N daqiqa keyin" ishlashi kerak bo'lgan vazifa — cron asoslari dagi aniqlik haqidagi eslatma aynan shu yerga yo'naltirgan holat: timer’dan foydalaning, chunki cron buni ifodalay olmaydi.
Aniqlik va yuklamani taqsimlash: AccuracySec va RandomizedDelaySec
Standart holatda timer so'ralgan aniq soniyada ishga tushmaydi. AccuracySec= ning standart qiymati 1 daqiqa, shuning uchun systemd vazifani boshqa uyg'onishlar bilan birlashtirib, energiyani tejash uchun uni bir daqiqagacha kechiktirishi mumkin. Haqiqatan aniq soniyada ishga tushishi kerak bo'lgan vazifa buni alohida so'rashi kerak:
RandomizedDelaySec= esa teskarisini qiladi va u cron’ga nisbatan haqiqiy production afzalligi. U har bir ishga tushirishga ko'rsatilgan qiymatgacha bo'lgan tasodifiy kechikish qo'shadi:
Bir xil daily backup’ni ishga tushiradigan yuzta serverdan iborat parkda oddiy 0 0 * * * cron qatori har bir hostni yarim tunda bir vaqtning o'zida backup manziliga murojaat qilishga majbur qiladi. Bu tarmoq va manzil uchun o'zimiz yaratgan "thundering herd" muammosi. RandomizedDelaySec=1h shu yuzta ishga tushirishni hostlar o'rtasida hech qanday kelishuvsiz yarim tundan keyingi bir soat davomida tasodifiy tarqatadi. cron bilan xuddi shunga erishish uchun har bir hostning jadvalini birma-bir qo'lda siljitib chiqishga to'g'ri keladi.
cron va systemd timer: qachon qaysi birini tanlash kerak
| Mezon | cron | systemd timer |
|---|---|---|
| Sintaksis soddaligi | Bitta qator, tez yoziladi | Ikkita fayl, ko'proq shablon kod |
| Chiqish va xatolarni kuzatish | Alohida sozlash kerak (email, log fayl) | Avtomatik, journalctl orqali |
| O'tkazib yuborilgan vazifani qayta ishga tushirish (tizim o'chiq bo'lgan) | Yo'q | Ha, Persistent=true bilan |
| Keyingi ishga tushish vaqtini oldindan ko'rish | Qiyin | Oson, systemctl list-timers bilan |
| Boshqa systemd unit’ga bog'liqlik (masalan, tarmoq ko'tarilgandan keyin) | Yo'q | Ha, Wants=, After= bilan |
| Konteynerlashtirilgan yoki minimal muhitlar | Ko'pincha allaqachon o'rnatilgan | systemd talab qiladi (ba’zi konteynerlarda yo'q) |
| Tanishlik va hujjatlar | Juda keng tarqalgan, deyarli hamma joyda tanish | systemd’ga asoslangan tizimlarda keng tarqalgan, lekin cron kabi universal emas |
Amalda ikkalasi ham to'g'ri javob bo'lishi mumkin. Mavjud, systemd’ga asoslangan serverda kuzatuvchanlik yoki bog'liqliklar kerak bo'lgan murakkabroq vazifalar uchun timer qulayroq. Keyinchalik boshqa turdagi tizimga ko'chirilishi mumkin bo'lgan oddiy, tez yoziladigan vazifalar uchun esa cron amaliy tanlov bo'lib qolaveradi.
Keng tarqalgan xatolar
.serviceni yoqib,.timerni unutish. Yolg'izsystemctl enable log-cleanup.servicehech narsani jadval bo'yicha ishga tushirmaydi —Type=oneshotservis faqat uning timer’i ishga tushganda yoki qo'lda boshlanganda ishlaydi. Yoqilishi kerak bo'lgan unit —.timerfayli.daemon-reloadni unutish. Unit faylni yaratgan yoki tahrirlagandan keyinsystemctl daemon-reloado'tkazib yuborilsa, systemd unit haqidagi oldingi, eskirgan tasavvuri bilan ishlashda davom etadi.Persistent=trueni cron xatti-harakati bilan chalkashtirish.Persistent=truefaqat server o'chiq bo'lgan paytda o'tkazib yuborilgan ishga tushirishning o'rnini to'ldiradi. cron’da umuman bunga teng sozlama yo'q — tizim ishlamay turgan vaqtga rejalashtirilgan vazifa shunchaki o'tkazib yuboriladi va hech qachon bajarilmaydi.- Hech qachon ishga tushmaydigan, aniq xatosi ham yo'q timer. Uni tartib bilan diagnostika qiling:
systemctl list-timers --allni ishga tushiring. Agar timer umuman ro'yxatda bo'lmasa, u hech qachon yoqilmagan/ishga tushirilmagan (--nowtushirib qoldirilgan yokidaemon-reloado'tkazib yuborilgan). Agar u ro'yxatda bo'lsa-yu,NEXTn/ani ko'rsatsa,OnCalendar=ifodasi noto'g'ri — uni alohidasystemd-analyze calendar '<expr>'bilan tekshiring. Agar jadval to'g'ri bo'lsa-yu, vazifa baribir noto'g'ri ishlasa,systemctl status <name>.timerunit yuklanishidagi xatolarni,journalctl -u <name>.serviceesa u oxirgi marta haqiqatan ishga tushganda nima bo'lganini ko'rsatadi.
Mashqlar
echo/dateni ishga tushiradigan oddiyType=oneshotservis yarating va uni har 5 daqiqada ishga tushadigan timer (OnCalendar=*:0/5) bilan juftlang.- Keyingi rejalashtirilgan ishga tushirishni
systemctl list-timersbilan kuzating, keyin chiqishnijournalctl -ubilan tasdiqlang. - Uchta turli
OnCalendar=ifodasinisystemd-analyze calendarbilan tekshiring va "Next elapse" natijasini o'zingiz kutgan natija bilan taqqoslang. - Bir xil vazifani avval cron qatori, keyin systemd timer sifatida yozing va har biri qancha sozlashni talab qilganini taqqoslang.
Xulosa
systemd timer cron bilan bir xil maqsadga — buyruqni jadval bo'yicha ishga tushirishga — xizmat qiladi, lekin buni alohida .service/.timer fayllar jufti, journalctl orqali avtomatik log yozish va Persistent=true kabi qo'shimchalar orqali amalga oshiradi. Oddiy, tez yoziladigan vazifalar uchun cron amaliy bo'lib qolaveradi. Yaqinroq kuzatuv yoki unit bog'liqliklari kerak bo'lgan vazifalar uchun esa systemd timer ko'proq nazorat beradi.