Teknoloji

cron mu systemd Timer mı? Neden, Nasıl ve Ne Zaman Hangisini Seçmeli?

İçindekiler

Ofiste Bir Sabah: Bir Cron Kaydı, Bir Sessizlik ve Bir Fark Ediş

Hiç başınıza geldi mi? Bir sabah ofise girersiniz, kahveyi koyarsınız, monitörün karşısına geçer ve “dün gece yedekleme çalıştı mı?” diye hafif bir iç şüpheyle bakarsınız. Benim başıma bu, tahmin ettiğimden daha fazla geldi. Bir seferinde kritik bir yedekleme işi, günlerdir sessiz sedasız patlıyormuş; ne mail gelmiş, ne alarm çalmış. Cron kaydında minicik bir PATH detayı yüzünden komut bulunamamış. İşte o sabah düşündüm ki, zamanlanmış işler sanki görünmez bir dişli gibi dönüyor ama bir diş atlayınca kimse duymuyor. Sonra bir arkadaş “Neden systemd timer denemiyorsun?” dedi. O gün bir ampul yandı.

Bu yazıda, cron ile systemd timer’ların günlük hayattaki halleri üzerinden gideceğiz. Hangisini, ne zaman, nasıl kullanınca gönlünüz rahat eder, onu konuşacağız. Sadece teknik cümleler değil; örnek unit dosyaları, küçük script’ler, healthcheck pingi, kilitleme, yeniden deneme ve “unutursam, kaçan işleri yakalar mı?” gibi sorulara da dokunacağım. Mesela şöyle düşünün: Gece yarısı bir yedek alacaksınız, ağ bir an gidip gelebilir, disk belli bir süre yoğun olabilir. Bu dünyanın doğası böyle. Mesele şu: Zamanlayıcınız bu iniş çıkışları müsamaha ile karşılayabiliyor mu? Ben de tam bunu anlatmak istiyorum.

Zamanlanmış İşler Neden Kırılır? Küçük Taşlar, Büyük Dalgalar

Görünmez Varsayımlar

Zamanlanmış işlerin en büyük düşmanı, görünmez varsayımlar. Cron, varsayılan ortam değişkenleri çok kısıtlı olduğu için, terminalde çalışan komut geceleri cron’da çalışmayabiliyor. “Ben bunu elle çalıştırınca oluyor” cümlesi genelde buradan gelir. PATH dar, HOME beklediğiniz gibi değil, locale ayarları yok. Script’iniz tam yoldan bağımsız davranmıyorsa, bir anda gece koşullarında tıkanır.

Çakışan Çalışmalar

Bir iş uzarsa ve yeni tetikleme aynı anda gelirse, iki kopya aynı veritabanına sarılıp kalabilir. Bir yedek hala sürerken ikinci yedek başlarsa, IO’yu gömebilirsiniz. Dosyaların üstüne yazılabilir, kilit mekanizması yoksa veri yarım kalır. İki işlem birbirini boğar ve sabah “neden bu kadar yavaş?” diye kendinizi sorgularken bulursunuz.

Kaçan Aralıklar

Makine gece kapalıysa veya yeniden başlıyorsa, 03:00’deki iş kaçar. Bazı senaryolarda bu sorun değil; bazen de ertesi gün yoklama listesinde büyük bir boşluk demek. “Dün çalışmadıysa ilk açılışta telafi et” gibi bir kalıcılık beklentisi doğar. Ve burada hangisini seçeceğimiz sorusu yavaş yavaş netleşir.

Cron’un Sade Dünyası: Basit, Hızlı, Ama Birkaç Tuzakla

Bir Klasik: crontab

Cron, basit olduğu için seviliyor. Bir satır yazarsınız, belirli dakikalarda tetikler. Mesela saat 03:15’te günlük yedek almak için şöyle bir kayıt düşülebilir:

# crontab -e
15 3 * * * /usr/local/bin/backup.sh >/var/log/backup.log 2>&1

Bu kadar yalın bir dünyada işler yürüyor. Fakat bu yalınlığın bir bedeli var. Ortam değişkenleri neredeyse boş. Bu yüzden komutlarınız için ya mutlak yollar kullanmanız ya da crontab’ın başına PATH ve benzeri değişkenleri açıkça yazmanız gerekiyor.

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=""
SHELL=/bin/bash

Bir de çakışma meselesi var. “Bir anda iki yedekleme çalışmasın” diyorsanız, küçük bir kilit mekanizması kullanmak iyi geliyor. Bunun için flock çok pratik:

15 3 * * * flock -n /var/run/backup.lock /usr/local/bin/backup.sh >>/var/log/backup.log 2>&1

Bu sayede kilit dosyası varken ikinci kopya başlamaz. Eğer bir de başarısızlık olursa haberiniz olsun istiyorsanız, cron’un e-posta özelliği var ama herkes posta sunucusu kurmak istemiyor. Yine de basit bir curl ping’i ile dışarıya “oldu/olmadı” diye haber uçurabilirsiniz. Bunun için çok kullanışlı servisler var; örneğin healthchecks.io, başarılarda ve hatalarda ayrı URL’lere ping atmanıza izin veriyor. “Ne zamandır koşmadı?” diye bir tahta gibi görebilmek insanın içini ferahlatıyor.

cron’un güzel yanı, sistemin dışında bir dünya kurmaması. Sadece tetikleme yapıyor, gerisi size kalıyor. Bu özgürlük tatlı, ama bazı durumlarda biraz fazla özgür. Günün sonunda, gözünüzün üstünde bir göz arıyorsanız, orada systemd timer’lar devreye giriyor.

Daha sağlam yedek alma senaryolarını seviyorsanız, uygulama-tutarlılığı ve dondurma/çözme akışını anlattığım detaylı rehber, zamanlanmış işlerin nasıl hassaslaştırılacağını da çağrıştırır: LVM snapshot ve fsfreeze ile uygulama‑tutarlı yedekler.

systemd Timer’ların Dünyası: Bir Tık Daha Şefkatli Otomasyon

Timer + Service: İkili Yapı

systemd timer’lar, işin tetikleyicisi ile işin kendisini ayrı düşünüyor. Bir service unit, bir de timer unit. Bu ayrım ilk başta formal görünebilir ama pratikte çok rahatlatıcı. Çalışma ortamını, günlükleri, kaynak sınırlarını, başarısızlıkta davranışı servis tarafında yönetir; tetikleme saatlerini timer tarafında ayarlarsınız.

Mesela günlük yedekleme için bir servis tanımı şöyle olabilir:

[Unit]
Description=Gece Yedekleme İşi
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/backup.env
ExecStart=/usr/local/bin/backup.sh
WorkingDirectory=/var/lib/backup
User=backup
Group=backup
# Kaynakları terbiye etmek rahatlatır
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=7
# Loglar journald'a düşer
StandardOutput=journal
StandardError=journal
# Başarısızlıkta yeniden deneme için basit kural
Restart=on-failure
RestartSec=30s

[Install]
WantedBy=multi-user.target

Ve bunun zamanlayıcısı:

[Unit]
Description=Gece Yedekleme Zamanlayıcısı

[Timer]
OnCalendar=03:15
Persistent=true
RandomizedDelaySec=2m
Unit=backup.service

[Install]
WantedBy=timers.target

Persistent=true en sevdiğimlerden. Makine 03:15’te kapalıydı diyelim; açıldığında “en son ne zaman çalıştırmıştım?” diye bakar ve kaçan işi telafi eder. RandomizedDelaySec ise çok sayıda sunucunuz varsa hepsinin aynı anda IO’ya abanmasını engeller. Küçük bir gecikme, büyük bir nefes.

Timer ifadeleri de esnek. “Her beş dakikada bir ama ilk boot’tan bir dakika sonra” gibi kalıplar kolay. “Günde bir, ama pazarları değil” diyebiliyorsunuz. Ayrıntı merak ederseniz, resmi belgelerde güzel örnekler var: systemd.timer referansı.

Ortam ve Günlükler

systemd size EnvironmentFile ile tertemiz bir ortam sağlama imkânı veriyor. Üstelik günlükler journald’a düştüğü için “ne oldu, ne olmadı”yı tek yerden görüyorsunuz. “Mail server kurayım mı?” sorusu da mecburi olmaktan çıkıyor. journalctl ile tarihe, unit’e göre filtreleyip bakmak huzur veriyor.

Koşullar ve Bağımlılıklar

Bir işin şebekeye ihtiyaç duyduğunu biliyorsanız, After=network-online.target ile söylemek çok iyi. Bazen de “şu dosya yoksa hiç uğraşma” gibi koşullar yazmak isteyebilirsiniz. Bu detaylar, gece nöbetinizde rastgele hatalar yerine kontrollü davranış getiriyor.

Timer’larla birlikte bir de systemd-run var; “hemen şimdi, aynı servis kurallarıyla bir kere çalıştır” dediğinizde tek seferlik işler için muazzam. “Birazdan bir sefer çalışsın ve logları aynı yere düşsün” demek için birebir.

“Bizim Script Hâlâ Bizim”: Esneklik

En güzel tarafı şu: Script’inizi değiştirmek zorunda değilsiniz. Hatta flock kilidi gibi alışkanlıklarınızı sürdürebilirsiniz. systemd, “ben sadece koşullarını iyileştiriyorum” diyor. O yüzden cron’dan timer’a geçiş, çoğu zaman birkaç unit dosyası yazmak kadar basit oluyor.

Sağlam Desenler: Kilit, Idempotent, Yeniden Deneme, Sağlık Nabzı

Kilit ve Çakışma Yönetimi

İşler çakışmasın diye flock alışkanlığını sürdürmek iyi fikir. Servis tanımına doğrudan eklemek mümkün. Mesela:

[Service]
Type=oneshot
ExecStart=/usr/bin/flock -n /var/run/backup.lock /usr/local/bin/backup.sh

Bu sayede timer arka arkaya tetiklese bile ikinci iş beklemeden elenir. Günün sonunda veriyi koruyan bu küçücük kilit, uykunuzu da koruyor.

Idempotent Davranış

“İki kere çalışırsa da sonuç aynı olsun” prensibi altın değerinde. Yedek dosyasına tarih eklemek, geçici dizin kullanmak, “başladı, sürüyor, bitti” gibi durum dosyaları tutmak çok iş görüyor. Aksi halde, yarım kalan bir işin artıkları, ertesi gecenin işini de sabote edebiliyor.

Yeniden Deneme ve Geri Basınç

Bazen hatayı kabullenmek değil, biraz sabır gerekir. Ağ bir an düşer, uç servis cevap vermez. Script içine basit bir yeniden deneme koymak çoğu kez yeterli. Küçük bir örnek:

#!/usr/bin/env bash
set -euo pipefail
attempts=0
max=5
sleep_base=5

until /usr/local/bin/backup_core.sh; do
  attempts=$((attempts+1))
  if [[ $attempts -ge $max ]]; then
    echo "denemeler tükendi" >&2
    exit 1
  fi
  sleep $((sleep_base * attempts))
  echo "yeniden deniyorum (#$attempts)"
done

Bu küçük geri basınç, kısa süreli sarsıntılarda işi kurtarır. systemd tarafında da Restart=on-failure ve StartLimitIntervalSec/StartLimitBurst gibi ayarlarla, işin panik halinde kendini kör dövüşüne sokmasını engelleyebilirsiniz.

Healthcheck Nabzı: Oldu mu, Olmadı mı?

Bir işi kurup unuttuğunuzda, unutulan şey genellikle “biliyor muyum?” sorusudur. Ben burada dış bir healthcheck servisini seviyorum. Başarılı bitişte bir success URL’e, hata anında bir fail URL’e ping atmak kadar temiz bir geri bildirim az bulunur. Bir curl ile şu hale gelir:

#!/usr/bin/env bash
set -euo pipefail
HC_OK="https://hc.example/success-uuid"
HC_FAIL="https://hc.example/fail-uuid"

trap 'curl -fsS -m 10 "$HC_FAIL" >/dev/null || true' ERR

# iş mantığı buraya
/usr/local/bin/backup_one_shot

curl -fsS -m 10 "$HC_OK" >/dev/null || true

Başlangıçta bir “start ping” atmak isterseniz, üçlü bir şablon da var. Böylece “neden uzun sürdü?” diye merak ettiğinizde gecikmenin nerede başladığını bilirsiniz. Bunun için healthchecks.io gibi servisler pratik bir pano sunuyor.

Günlükler ve Ayıklama

Journald ile günlükler tek yerde. “Dün 03:15’te ne oldu?” sorusuna cevap ararken şu komut çok iş görüyor:

journalctl -u backup.service --since "2025-01-01" --until "2025-01-02"

Yine de, bazıları düz dosya loglarını da sever. O da mümkün. StandardOutput=append:/var/log/backup.log gibi bir yönlendirme ile dosyada birikmesini sağlayabilirsiniz. Esneklik elinizde.

Gerçek Hayattan Senaryolar: “Mesela Şöyle Düşünün”

SSL Yenileme: Kaçarsa Üşütür

Sertifikalar yenilenmezse bir sabah tarayıcılar bağırır. Yenileme işi sık aralıklarla ve sağlam yapılmalı. Bu tür işler, “kaçarsa açılışta telafi et” özelliğiyle systemd timer’da daha güvenli hissedilir. Üstelik başarısızlıkta birkaç dakika sonra otomatik deneme rahatlatır. Sertifika otomasyonunu yedekli CA ile kurduğunuz bir düzende bu daha da kritik. Bu bağlamda, ACME otomasyonunda yedekli CA kurulumunu biraz kurcalayın; zamanlayıcıyı nasıl düşünmeniz gerektiği konusunda fikir veriyor.

Veritabanı Yedekleri: Sessiz Kahramanlar

Veritabanı yedekleri gecenin sessiz kahramanlarıdır. IO’nun sakin olduğu saatleri kollamak istersiniz ama işler bazen uzayabilir. systemd timer’ın RandomizedDelaySec özelliği, çok sunuculu ortamlarda aynı anda abanmayı engelleyerek diskleri mutlu eder. Ağ kopup gelirse, yeniden deneme ve kilitleme kombinasyonuyla sabaha sorun taşımadan çıkarsınız.

Canary Yayın: Sağlığa Bak, Sonra Yaygınlaştır

Uygulama dağıtımı sonrası “kalp atışı normal mi?”yi sormadan herkese yaymak cesur bir iş. Küçük bir timera bağlı sağlık kontrolüyle, dağıtım penceresinde nabız tutmak hoş oluyor. Eğer bu konu ilginizi çekiyorsa, yönlendirme ve sağlık kontrolünü birlikte anlattığım şu yazı iyi gider: VPS’te canary dağıtımı ve sağlık kontrolü.

Küme Yaşamı: Kalbin Attığı Yer

Küme sistemlerinde arka planda dönen işler çoktur: node temizliği, imaj güncellemeleri, küçük housekeeping görevleri. Timer’lar burada düzen getiriyor. “Her node rastgele 10 dakika içinde çalışsın” gibi bir davranış, tüm kümeye yumuşak bir ritim verir. Kümelerle ilgili daha geniş resim görmek isterseniz, 3 VPS ile K3s yüksek erişilebilirlik rehberini de seversiniz.

Felaket Dayanıklılığı: Nabızsız Gece Olmasın

İşlerin hepsi tek merkezde koşuyorsa, bir aksama tüm akışı durdurur. Timer’lar ve healthcheck pingiyle, uzak bir panoda “bu gece kim koştu, kim koşmadı?”yı görmek, felaket senaryolarından önce küçük aksaklıkları yakalatır. Mimarilerin dayanıklılık tarafını merak edenler için şu rehberler güzel bir eşlikçi oluyor: çok bölgeli mimarilerle felaket dayanıklılığı ve çoklu sağlayıcı DNS ile geçiş ve dayanıklılık. Bu metinlerdeki düşünme biçimi, zamanlayıcılarınızı tasarlarken de işliyor.

cron mu systemd Timer mı? Ne Zaman Hangisi Daha Doğal Hisseder?

Sadelik Arıyorsanız

Tek bir komutu, basit bir saat ifadesiyle ateşlemek istiyorsunuz ve makine hep açık. Ortam değişkenlerini açık açık yazmayı dert etmiyorsunuz. Logları bir dosyaya akıtıp ara sıra bakarım diyorsanız, cron burada hâlâ keyifli bir tercih. Üstelik sistemi hiç zorlamadan, hemen şimdi kayda geçersiniz. Referans için crontab sayfasını da el altında tutmak güzel: crontab(5) el kitabı.

Güvenilirlik, Telafi ve Gözlem İstiyorsanız

“Kaçan işi telafi etsin, loglar journald’a düşsün, bağımlılıkları tanımlayayım, kaynakları sınırlayayım, başarısızlıkta nezaketle yeniden denesin” diyorsanız, systemd timer doğal bir ev. Özellikle gece görevlerinde ve küme senaryolarında gönül rahatlığı veriyor. Bir de RandomizedDelaySec gibi küçük incelikler, büyük kalabalıklarda hayat kurtarıyor.

İkisinin Yan Yana Yaşaması

Bu bir “ya o, ya bu” hikâyesi değil. Kimi sunucularda cron, kimilerinde timer; hatta aynı makinede farklı işler için ikisi birden. “Eldeki işi en iyi kim yapar?” sorusuyla seçmek, uzun vadede daha sağlıklı. Benim alışkanlığım, kritikliğin arttığı yerde timer’a meyletmek, çok basit ve hızlı işlerde cron’u korumak. Zamanla bazı cron görevlerini timer’a taşıyıp rahatladığımı itiraf edeyim.

Uçtan Uca Örnek: Yedekle, Kontrol Et, Bildir

Dosya Düzeni

Şöyle küçük bir düzen düşünün: /usr/local/bin/backup.sh asıl işi yapıyor, kilit ve yeniden denemeyi içinde hallediyor, başarı/başarısızlıkta healthcheck’e ping atıyor. Ortam değişkenleri için /etc/backup.env, servis ve timer da aşağıdaki gibi:

# /etc/backup.env
BACKUP_SRC=/var/lib/app
BACKUP_DST=/var/backups/app
HC_OK=https://hc.example/success-uuid
HC_FAIL=https://hc.example/fail-uuid
# /usr/local/bin/backup.sh
#!/usr/bin/env bash
set -euo pipefail
: "${BACKUP_SRC:?}"
: "${BACKUP_DST:?}"
: "${HC_OK:?}"
: "${HC_FAIL:?}"

trap 'curl -fsS -m 10 "$HC_FAIL" >/dev/null || true' ERR

exec 9> /var/run/backup.lock
flock -n 9 || { echo "kilit alinamadi, zaten calisiyor"; exit 0; }

attempt=0
max=3
while true; do
  rsync -a --delete "$BACKUP_SRC/" "$BACKUP_DST/"
  status=$?
  if [[ $status -eq 0 ]]; then
    break
  fi
  attempt=$((attempt+1))
  [[ $attempt -ge $max ]] && exit $status
  sleep $((attempt * 10))
  echo "yeniden deneme: $attempt"
done

curl -fsS -m 10 "$HC_OK" >/dev/null || true
# /etc/systemd/system/backup.service
[Unit]
Description=Uygulama Yedekleme
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/backup.env
ExecStart=/usr/local/bin/backup.sh
User=backup
Group=backup
WorkingDirectory=/
StandardOutput=journal
StandardError=journal
Restart=on-failure
RestartSec=20s

[Install]
WantedBy=multi-user.target
# /etc/systemd/system/backup.timer
[Unit]
Description=Uygulama Yedekleme - Gecelik

[Timer]
OnCalendar=03:15
Persistent=true
RandomizedDelaySec=90
Unit=backup.service

[Install]
WantedBy=timers.target

Bu kurgu küçük ama güçlü. Kaçan işleri telafi eder, çakışmayı önler, kısa kesintilerde yeniden dener, sonunda bir ping ile “ben iyiyim” diye haber verir. Aynı yaklaşımı sertifika yenileme, rapor üretme, indeksleme gibi işlere de kolayca uyarlayabilirsiniz.

Healthcheck İzleme: Pano, Alarm ve Huzur

Kalp Atışını Görmek

Birçok kişi için zamanlanmış işin en zor kısmı, “unutup gittiğimde kim beni uyandıracak?” sorusu. Dış bir pano ve basit ping URL’leri bu sorunu çok pratik çözüyor. Bir bakışta, yeşil mi kırmızı mı görürsünüz. Süre aşımını, en uzun koşuyu, son hatayı tek bakışta fark etmek kolaylaşır. Bu panoyu Slack veya e-posta ile bağlamak da bir iki tık.

Başarısızlıktan Öğrenme

Ping’ler sadece alarm değildir; küçük bir hafıza da oluşturur. “Son üç gece neden uzadı?” sorusuna, raporlara bakınca ağdaki bir tıkanma ya da disk yoğunluğu kendini ele verir. Böyle anlarda, timer’ın RandomizedDelaySec ayarıyla oynamak, cron’daysanız işin saatini hafif kaydırmak güzel sonuç verir. Küçük dokunuşlarla gecenin ritmini düzeltirsiniz.

Belgeleme ve Runbook

Görevin başına kısa bir açıklama, beklenen süresi ve “panik anında ne yapacağız?” notu koymayı seviyorum. Küçük bir runbook, gecenin bir yarısı gelen bildirimde saatler kazandırıyor. İlgili bir konuda, replikasyon ve felaket senaryolarında bu zihniyeti nasıl çerçevelediğimi şu yazıda uzunca anlattım: S3/MinIO çapraz bölge replikasyon ve DR runbook. Oradaki yaklaşım, burada da bire bir çalışıyor.

Sürprizler İçin Küçük Hileler

Calendar İfadeleri ile İncelik

“Ayın son iş günü çalış, pazarları es geç, her 15 dakikada ama 5 dakika kaydırarak başla” gibi ince ayarlarınız varsa, timer’ın takvimi cömert. “Mon..Fri 23:00” ya da “*-*-01 04:00” gibi kalıplarla akışı kurcalayabilirsiniz. Detaylar için systemd sayfasında güzel bir bölüm var; “OnCalendar” adeta küçük bir dil gibi: systemd.timer OnCalendar.

Ad Hoc Çalıştırma

“Şimdi, bir kere” istiyorsunuz ama servis davranışları da geçerli olsun. systemd-run burada yıldız gibi parlıyor. Örneğin:

systemd-run --unit=ad-hoc-backup --on-active=5s /usr/local/bin/backup.sh

Beş saniye sonra, aynı günlük ve politika çerçevesinde koşar. Üstelik “bu bir defalık” olduğu için yapı dağılmıyor.

cron Kullanmaya Devam Edenlere Minik Hatırlatma

cron’dan kopmak istemiyorsanız, küçük bir sağlık pingi ve flock ile çok yol alırsınız. Ayrıca, satır başına PATH’i açık yazmak, set -euo pipefail ile script’leri daha gergin çalıştırmak ve logları zaman damgalı döndürmek iyi pratikler. Kafanızda takılan formatlar için şu sayfayı sık ziyaret ederim: crontab(5) el kitabı.

Kapanış: Güvenilirlik, Küçük Jestlerin Toplamıdır

Bir zamanlayıcının güvenilirliği, tek bir özelliğin değil, küçük jestlerin toplamı. Biraz kilit, biraz yeniden deneme, kaçan işleri yakalama, logları net görmek, bir de görünmeyen bir el gibi kalp atışını kontrol eden healthcheck. cron ile systemd timer arasında dolaşırken, şunu unutmayın: En doğru araç, sizin rahat uyuduğunuz araçtır. Eğer “kaçarsa telafi etsin, günlükler elimde olsun, koşullarım belli olsun” diyorsanız, timer sizi sarıp sarmalar. “Hemen yazayım, küçük bir iş, dosyaya loglarım yeter” diyorsanız, cron hâlâ efsane.

Pratik bir tavsiye ile bitireyim. Kritik işlerde timer’ı deneyin, healthcheck pingi ekleyin ve küçük bir runbook yazın. Daha basit işlerde cron’a devam edin ama flock’tan ve açık PATH’ten vazgeçmeyin. Bir de, dağıtım ve sağlık takibi gibi konularla ilgileniyorsanız, bu yazıya eşlik edecek bir okuma olarak canary dağıtımıyla sağlığı kollamak ve kümelerde üretim‑hazır kurulum iyi gider. Umarım bu yazı size faydalı olmuştur. Bir dahaki yazıda görüşmek üzere; o zamana kadar, zamanlayıcılarınız nazik olsun, işleriniz de sessizce, güvenle aksın.

Sıkça Sorulan Sorular

İş çok basit ve makine hep açıksa cron gayet yeterli. Kaçan işleri telafi etmek, logları journald’de görmek ve koşullar tanımlamak istiyorsan systemd timer daha rahat.

Script’e küçük bir flock kilidi ekle. Böylece ikinci tetikleme geldiğinde iş zaten çalışıyorsa yenisi başlamaz. systemd kullanıyorsan bu çağrıyı ExecStart içine koyabilirsin.

İşe bir healthcheck pingi ekle. Başarıda ve hatada ayrı URL’lere ping at. Dış panoda son koşuyu, gecikmeleri ve kesintileri tek bakışta görür, gecenin bir yarısı sürpriz yaşamazsın.