Follow

Systemd Timers ile Cron’dan Göç: Pratik Rehber ve Örnekler

🎧 Bu yazıyı dinleyebilirsiniz

Uzun yıllardır sunucularda cron ile idare ettim; küçük script’leri sabitlemek ve unutmamak pratik geliyordu. Ancak bir süre sonra zamanlama, logging ve kaçırılan çalışmaları yönetmek zorlaştı. Systemd timer’lara geçince, işleri daha kontrollü, izlenebilir ve güvenli hale getirdim. Aşağıda gerçek dünyada işe yarayan adımları, örnek unit dosyalarını ve dikkat edilmesi gereken noktaları paylaşıyorum.

Neden systemd timer?

Benim için üç ana sebep öne çıktı: merkezi loglama (journal), boot sonrası kaçırılan görevleri yakalama (Persistent=yes) ve birim bazında izin/çalışma ortamı tanımlama (User=, Environment=). Ayrıca timer’lar OnCalendar/OnBootSec gibi esnek tetikleyiciler sunuyor; yani sadece cron benzeri zamanlama değil, sistem olaylarına bağlanan işlemler de kolaylaşıyor.

Temel yapı: .service ve .timer

Her scheduled iş iki dosyayla modellenir: bir .service (yapılacak iş) ve onu hangi zamanlarda tetikleyeceğini söyleyen .timer. Basit bir örnek veriyorum.

# /etc/systemd/system/backup-db.service
[Unit]
Description=Günlük veritabanı yedeği

[Service]
Type=oneshot
User=backup
Group=backup
EnvironmentFile=/etc/default/backup-db
ExecStart=/usr/local/bin/backup-db.sh
TimeoutStartSec=1800

# /etc/systemd/system/backup-db.timer
[Unit]
Description=Günlük veritabanı yedeği timer

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

[Install]
WantedBy=timers.target

Açıklamalar kısaca: Persistent=true sistem kapalıyken kaçırılan tetiklemeyi tekrar çalıştırır; RandomizedDelaySec aynı anda çok sayıda sunucuda çakışmayı azaltır; TimeoutStartSec uzun çalışan işlemleri sınırlar.

Cron’dan geçiş adımları (pratik sıra)

  • 1) Cron girdilerini envanterle: crontab -l, /etc/cron.* ve servis hesabı crontab’larını topla.
  • 2) Her komut için bir servis dosyası tasarla; komutu doğrudan ExecStart içine koyma — wrapper script kullan. Bu, ortam değişkenleri ve loglama için temiz olur.
  • 3) Zamanlamayı timer’a çevir: cron zamanını OnCalendar veya OnActiveSec ile eşleştir. (Ör: her gece 02:30 için OnCalendar=*-*-* 02:30:00.)
  • 4) Persistent ihtiyacını değerlendir. Kaçırılan çalışmaları çalıştırmak istiyorsan Persistent=yes ekle.
  • 5) Overlap (üst üste çalışma) kontrolü ekle: systemd’nin yerleşik tekil çalıştırma kontrolü sınırlı olduğu için flock kullan; wrapper içinde flock -n /var/lock/myjob.lock şeklinde kilitle.
  • 6) Yükle, test et ve izlemeye al: systemctl daemon-reload, systemctl enable --now myjob.timer, sonra systemctl list-timers --all ve journalctl -u myjob.service -f.

Çakışma ve tekil çalıştırma (concurrency) yönetimi

Ben genelde flock kullanıyorum çünkü güvenilir ve basit. Service içinde şöyle:

ExecStart=/usr/bin/flock -n /var/lock/backup-db.lock /usr/local/bin/backup-db.sh

Eğer flock yoksa, script içinde PID file kontrolü veya systemd’nin RuntimeMaxSec ile zaman sınırı eklemek ikinci tercihim. Ancak gerçek tekil-lock için flock en pratiktir.

Loglama ve hata takibi

Artık her iş journal’a yazılıyor. Hızlı kontroller için benim kullandığım komutlar:

systemctl list-timers --all --no-pager
systemctl status backup-db.timer backup-db.service
journalctl -u backup-db.service -n 200 -f

Hatalı durumlarda servis çıkış kodunu ve journalctl -u çıktısını inceleyin. İhtiyaç varsa service içine StandardOutput=append:/var/log/myjob.log ile ilave dosya logu tutabilirsiniz (ama merkezi journal tercih edilir).

Kullanıcı seviyesinde timer’lar

Systemd kullanıcı timer’ları da var: --user ile yönetilir. Masaüstü araçları veya kullanıcının cron işlerini migrate ederken kullanışlıdır. Unutmayın: user timers için enable/ start yaparken systemctl --user enable --now myjob.timer kullanın ve kullanıcı oturumunun systemd user instance’ının aktif olduğunu doğrulayın.

Pratik ipuçları ve sık yapılan hatalar

  • Timezone farklarını netleyin: OnCalendar genelde sistem saat dilimini kullanır; kritik zamanlarda TZ belirtin veya UTC standardı benimseyin.
  • Çevresel değişkenleri EnvironmentFile ile yönetin; unit içine uzun env yazmaktan kaçının.
  • Daemon-reload unutmayın; birimleri değiştirdikten sonra systemctl daemon-reload gerekli.
  • Karmaşık zincirlerde Wants= veya After= ile bağımlılık tanımlayın (ör. network-online.target).
  • Timer’ı başlatmadan önce hizmeti manuel çalıştırıp çıktıyı kontrol edin; hatayı erken yakalarsınız.

Kapanış olarak: cron’ı tamamen kötülemiyorum — küçük, tek seferlik makinelerde hâlâ işe yarıyor. Ama üretim sınıfında izlenebilirlik, hata kurtarma ve yönetilebilirlik istiyorsanız systemd timer’lar bana göre daha sürdürülebilir bir çözüm oldu. Birkaç basit wrapper script ve bir çift unit dosyasıyla sisteminizin zamanlanmış işler katmanını epey sağlamlaştırırsınız. Benim geçişimde en çok işe yarayan şey: ilk hafta loglara bakmaya vakit ayırmak oldu — orada göreceğiniz küçük hatalar, ileride büyük işler kaybetmenizi engeller.

Comments
Join the Discussion and Share Your Opinion
Add a Comment

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir


Newsletter
Join Design Community
Get the latest updates, creative tips, and exclusive resources straight to your inbox. Let’s explore the future of design and innovation together.