Üretimde en tehlikeli arıza sınıflarından biri “process yaşıyor ama iş yapmıyor” durumudur. CPU düşük, port açık, health check yeşil… ama kuyruk büyür, latency tırmanır ve sistem “yavaş yavaş ölür”. Bu tip takılmaları sadece Restart=always ile yakalamak zordur; çünkü process crash etmez.
systemd watchdog, tam bu sınıfa karşı iyi bir araçtır: servis belirli aralıkla “ben iyiyim” sinyali vermezse systemd servisi yeniden başlatır.
Watchdog neyi çözer, neyi çözmez?
Çözdüğü:
- deadlock / event loop kilitlenmesi
- dış dependency beklemesinde “sonsuz hang”
- servis içindeki “progress” kaybı
Çözmediği:
- yanlış iş mantığı (servis yanlış cevap veriyor ama hâlâ “yaşıyor”)
- dependency sorunları (DB yoksa restart loop ile daha kötü olabilir)
Temel unit dosyası (Type=notify + WatchdogSec)
Watchdog için servisinin sd_notify üzerinden READY/WATCHDOG sinyali vermesi gerekir. systemd tarafındaki baseline:
[Unit]
Description=My Service (with watchdog)
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
NotifyAccess=main
ExecStart=/usr/local/bin/my-service
WatchdogSec=30s
Restart=on-failure
RestartSec=3s
TimeoutStartSec=30s
TimeoutStopSec=20s
StartLimitIntervalSec=120s
StartLimitBurst=10
[Install]
WantedBy=multi-user.target
Bu unit’in mesajı şudur:
- servis 30 saniyeden uzun süre “WATCHDOG=1” sinyali vermezse restart edilir
- crash ederse restart edilir
- çok sık restart olursa (burst)
systemdfrenler
Servis tarafı: sağlık sinyali nasıl üretilecek?
İki pratik yaklaşım:
1) Uygulama içine notify eklemek (en doğru)
Servisin çalıştığı thread/event loop belirli aralıklarla sd_notify("WATCHDOG=1") üretir. READY sinyali de “gerçekten trafik alabilirim” noktasında verilmelidir.
2) Wrapper ile kısmi yaklaşım (sınırlı ama bazen yeterli)
Uygulama değiştirilemiyorsa, wrapper proses ile “progress” sinyali üretmeye çalışan desenler vardır; ama gerçek watchdog davranışı için yine notify entegrasyonu gerekir. Bu yüzden uzun vadeli hedef, uygulamanın notify desteklemesidir.
Operasyonel ayar: restart loop’u kontrol et
Watchdog devreye girince en hızlı bozulan şey “gürültü” olur. Şu kontrolleri koy:
StartLimit*ile fren- servis loglarına restart nedeni yaz (uygulama loglarında)
- alarmı sadece “çok sık restart” durumunda yükselt
Örnek triage komutları:
systemctl status my-service --no-pager
journalctl -u my-service -n 200 --no-pager
systemctl show my-service -p NRestarts -p RestartUSec -p WatchdogUSec
OnFailure ile alarm/otomasyon bağlama
İleri seviye ama çok faydalı: servis fail edince otomatik bir aksiyon tetiklemek (ticket, slack, script). Örnek:
[Unit]
OnFailure=my-service-failure@%n.service
Burada amaç “her restart’ta panik” değil; tekrarlayan failure’ı görünür kılmaktır.
Sonuç
Watchdog, üretimde “ölmedi ama takıldı” sınıfını azaltır ve MTTR’ı düşürür. Başarı; sadece WatchdogSec açmak değil, READY/WATCHDOG sinyalini doğru tanımlamak, restart storm riskini frenlemek ve alarmı doğru eşiğe bağlamaktır. Operasyonel liderlik açısından da bu, “servis ayakta” metriklerini daha dürüst hâle getirir.