Cron vs Systemd Timer Hangisini Ne Zaman Kullanmalısınız?

İleri KonularYayın: Güncellendi: 6 dk okumaHazırlayan: cronjob.com.tr Editörleri

Modern Linux dağıtımlarının çoğu systemd ile geldiğinden beri zamanlanmış görevler için iki güçlü seçenek var: klasik cron ve systemd timer birimleri. İkisi de belirlenen zamanda komut çalıştırır; loglama, bağımlılık, kaynak sınırı ve kaçan görev telafisinde ayrışırlar. Resmi referans: systemd.timer(5).

Bu rehber yan yana karşılaştırma, çalışan .service/.timer kurulumu, OnCalendar sözdizimi, gerçek senaryolar ve sık hata mesajlarını verir. Beş alanlı cron ifadeleri için crontab sözdizimi; kaçan günlük işler için ayrıca anacron seçeneği vardır.

Karar kuralı kısa: tek satırlık, taşınabilir iş → cron; servis bağımlılığı, journald, cgroup veya Persistent=true → systemd timer. İkisi aynı sunucuda birlikte çalışabilir.

Hızlı Karşılaştırma

ÖzellikCronSystemd Timer
Kurulum kolaylığıTek satır (crontab -e)İki dosya (.timer + .service)
LoglamaElle yönlendirme (>> log 2>&1)Otomatik — journalctl
Kaçan görev telafisiYok (anacron gerekir)Persistent=true (yalnız OnCalendar)
Servis bağımlılığıYokAfter=, Requires=
Kaynak sınırlamaYokcgroup: MemoryMax=, CPUQuota=
Çakışma korumasıElle (flock)Aynı servis üst üste başlamaz
Rastgele gecikmeElle sleepRandomizedDelaySec=
Saniye hassasiyetiYok (min. 1 dakika)Ayarlanabilir; varsayılan AccuracySec=1min
TaşınabilirlikHer Unix'te aynıYalnızca systemd'li Linux
Öğrenme eğrisiDüşükOrta

Systemd Timer Nasıl Kurulur?

Bir timer iki birimden oluşur: işi tanımlayan .service ve zamanlamayı tanımlayan .timer. Varsayılan eşleştirmede dosya adları aynı tabanı paylaşır (yedek.service + yedek.timer).

1. Service birimi

# /etc/systemd/system/yedek.service
[Unit]
Description=Gunluk veritabani yedegi
After=network-online.target mysql.service

[Service]
Type=oneshot
User=yedek_user
ExecStart=/opt/scripts/yedek.sh
MemoryMax=512M
Nice=10

Type=oneshot kısa süreli, bitince çıkan script'ler içindir. After= yalnızca sıralama garantisi verir; bağımlılığı da başlatmak için Requires= veya Wants= ekleyin; Wants= başarısız bağımlılıkta görevi engellemez.

2. Timer birimi

# /etc/systemd/system/yedek.timer
[Unit]
Description=Gunluk veritabani yedegi zamanlayicisi

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
RandomizedDelaySec=300

[Install]
WantedBy=timers.target

Persistent=true, timer kapalıyken (ör. makine kapalı) kaçan OnCalendar tetiklerini açılışta yakalar; man sayfasına göre yalnızca OnCalendar= ile etkilidir. RandomizedDelaySec= yükü yaymak için kullanılır; kalıcı tetikte de gecikme uygulanabilir.

3. Etkinleştirme ve izleme

  1. Dosyaları /etc/systemd/system/ altına yazın.
  2. sudo systemctl daemon-reload
  3. sudo systemctl enable --now yedek.timer
  4. systemctl list-timers ile sonraki çalışma zamanını doğrulayın.
  5. Zamanı beklemeden test: sudo systemctl start yedek.service
  6. Log: journalctl -u yedek.service -n 50 --no-pager
sudo systemctl daemon-reload
sudo systemctl enable --now yedek.timer
systemctl list-timers
journalctl -u yedek.service -n 50
sudo systemctl start yedek.service

OnCalendar Sözdizimi vs Cron

Cron'un 5 alanlı sözdizimi yerine systemd okunabilir takvim ifadeleri kullanır (systemd.time(7)):

ZamanlamaCronOnCalendar
Her gün 02:000 2 * * **-*-* 02:00:00
Her 15 dakikada*/15 * * * **:0/15
Hafta içi 09:000 9 * * 1-5Mon..Fri 09:00
Ayın 1'i 04:3030 4 1 * **-*-01 04:30:00
Her saat başı0 * * * *hourly

Test: systemd-analyze calendar "Mon..Fri 09:00". Cron ifadeleri için cron expression generator kullanabilirsiniz.

Gerçek Senaryolar

Senaryo 1: MySQL ayaktayken gece yedeği (timer)

After=mysql.service ve Requires=mysql.service ile yedek, MySQL biriminin başarılı başlangıcından sonra çalışır; veritabanının bağlantı kabul etmeye hazır olması servis türüne bağlıdır. MemoryMax=512M gece yedeğinin tüm RAM'i yemesini engeller. Log için ekstra yönlendirme gerekmez; journalctl -u yedek.service yeterlidir. Cron'da aynı bağımlılığı güvenilir kurmak zordur.

Senaryo 2: Her 5 dakikada kuyruk (cron)

*/5 * * * * /usr/bin/flock -n /tmp/kuyruk.lock /usr/bin/php /var/www/app/kuyruk.php >>/var/log/kuyruk.log 2>&1

Bağımsız, sık ve taşınabilir bir işte iki unit dosyası fazla tören olabilir. Çakışmayı flock, logu dosya yönlendirmesi ile çözersiniz. PATH tuzakları için cron job çalışmıyor listesine bakın.

Systemd Timer'ın Öne Çıktığı Senaryolar

Cron'un Hâlâ Kazandığı Senaryolar

İkisinin de koşullarınızı karşılamadığı durumlar — dağıtık ekip, HTTP tabanlı tetikleme, bulut zamanlayıcılar — cron alternatifleri karar tablosunda tek bakışta karşılaştırılmıştır.

Sık Hatalar ve Çözümleri

1. Failed to enable unit: Unit yedek.timer does not exist

Neden: Dosya yolu/adı yanlış veya daemon-reload atlandı.
Çözüm: /etc/systemd/system/yedek.timer olduğundan emin olun; daemon-reload çalıştırın.

2. Failed to parse calendar specification

Neden: Geçersiz OnCalendar.
Çözüm: systemd-analyze calendar "..." ile doğrulayın; cron sözdizimini olduğu gibi yapıştırmayın.

3. Timer aktif ama servis çalışmıyor

Neden: Service ExecStart yolu hatalı; kullanıcı izni; bağımlılık başarısız.
Çözüm: systemctl status yedek.service ve journalctl -u yedek.service -xe; script'i aynı kullanıcıyla elle çalıştırın.

4. Persistent=true beklenen telafiyi yapmıyor

Neden: Timer OnCalendar kullanmıyor (ör. yalnızca OnBootSec); veya state temizlenmiş.
Çözüm: Takvim ifadesi kullanın; state için man sayfasındaki systemctl clean --what=state uyarısını bilinçli uygulayın.

5. Unit dosyası değişti ama eski davranış sürüyor

Neden: daemon-reload veya timer restart unutuldu.
Çözüm: daemon-reload sonra systemctl restart yedek.timer.

cronjob.com.tr ile HTTP Tabanlı Alternatif

Hem cron hem systemd timer sunucu üzerinde yapılandırma ve bakım ister. Görev HTTP ile tetiklenebiliyorsa cronjob.com.tr unit dosyası veya crontab olmadan zamanlar. Ücretsiz; kayıtta kredi kartı istenmez. En kısa aralık 1 dakika; 5 alanlı cron ifadesi veya hazır aralık seçilebilir (saat dilimi iş bazında, varsayılan Europe/Istanbul).

<?php
declare(strict_types=1);
$beklenen = getenv('CRON_SECRET') ?: '';
$gelen = $_SERVER['HTTP_X_CRON_TOKEN'] ?? '';
if ($beklenen === '' || !hash_equals($beklenen, $gelen)) {
    http_response_code(403);
    exit('forbidden');
}
http_response_code(200);
echo 'ok';

Panelde URL, metot, özel header, isteğe bağlı gövde ve zamanlamayı girin. Başarı HTTP 200–399; en fazla 5 yönlendirme; TLS doğrulanır; localhost/özel ağa istek yok. Timeout aralığa göre (1 dk → 55 sn, cron ifadeli → 290 sn). Çalışma logları ~7 gün; ardışık hata eşiğinde e-posta.

Sıkça Sorulan Sorular (SSS)

Systemd timer cron'dan daha mı iyi?

Duruma bağlı. Systemd timer log yönetimi, servis bağımlılığı, kaynak sınırlama ve kaçan görev telafisi (Persistent=true) sunar; buna karşılık her görev için iki dosya (.timer + .service) gerektirir ve öğrenme eğrisi daha diktir. Tek satırlık basit görevlerde cron hâlâ en hızlı çözümdür.

Systemd timer'da kaçan görevler telafi edilir mi?

Evet. Timer'ın [Timer] bölümüne Persistent=true eklerseniz, makine kapalıyken kaçan görev bir sonraki açılışta otomatik çalıştırılır — anacron'a gerek kalmaz. Bu ayar yalnızca OnCalendar= kullanan timer'larda geçerlidir.

Systemd timer loglarını nasıl görürüm?

journalctl -u gorev-adi.service komutuyla görevin tüm çıktı ve hata kayıtlarını, systemctl list-timers --all komutuyla da tüm timer'ların son ve sonraki çalışma zamanlarını görebilirsiniz.

OnCalendar ifadesini nasıl test ederim?

systemd-analyze calendar "Mon..Fri 09:00" komutu bir sonraki tetiklenme zamanını gösterir. Hatalı takvim ifadesi burada veya timer yüklenirken ortaya çıkar.

User-level systemd timer kullanabilir miyim?

Evet. ~/.config/systemd/user/ altına .service ve .timer koyup systemctl --user enable --now kullanın. Oturum kapalıyken çalışması için linger (loginctl enable-linger) gerekebilir.

Sonuç

Tek satırlık, bağımsız ve taşınabilir görevlerde cron; bağımlılık, kaynak sınırı, merkezi log ve telafi gerektiren görevlerde systemd timer tercih edin. Doğru araç, görevin karmaşıklığına göre seçilir.

Sunucu Yapılandırmadan Cron Job Oluşturun

Unit dosyası veya crontab olmadan HTTPS işlerinizi panelden zamanlayın. Ücretsiz; kayıtta kredi kartı istenmez.

Ücretsiz Başla →

İlgili Rehberler