Üretim sistemlerinde, kritik bir hizmetin sessizce takılıp kalması—çökme yok, log spam yok, sadece duruk kalma—çok sık rastladığım bir durumdur. Kullanıcılar şikayet etmeye başlar, izleme araçları normal CPU kullanımını gösterir, fakat hizmet aslında işini yapmaz. Ortamımda, bu tür sessiz hataları yakalamak ve etkilerin yayılmasını önlemek için systemd’nin yerleşik WatchdogSec özelliğine güvenirim; bu sayede hizmet otomatik olarak yeniden başlatılır.
WatchdogSec systemd'de Nasıl Çalışır?
Bir hizmet birimi için WatchdogSec etkinleştirildiğinde, systemd, hizmetin sd_notify() fonksiyonu üzerinden WATCHDOG=1 sinyaliyle periyodik olarak kendine bildirim göndermesini bekler. Hizmet, yapılandırılmış aralık içinde bu ping'i gönderemezse, systemd hizmetin donduğunu varsayar ve eylem alır—genellikle Restart= ayarına göre yeniden başlatır.
Bu sadece bir zaman aşımı değildir; bu, aktif bir canlılık kontrolüdür. Hizmet, sd_notify() çağrısını yapacak şekilde enstrümantasyon yapılmış olmalıdır—nginx, Redis veya özel Go/Python uygulamaları gibi birçok modern daemon, kütüphaneler aracılığıyla bunu zaten destekler. Eğer hizmetiniz bunu desteklemiyorsa, systemd paketinden gelen watchdog adlı bir sarmalayıcı kullanabilirsiniz.
WatchdogSec Yapılandırması: Pratik Bir Örnek
Bazı yüklerde kilitlenebilen Python tabanlı bir API hizmeti için şu şekilde kurdum:
[Unit]
Description=Internal API Service
After=network.target
[Service]
ExecStart=/usr/local/bin/api-server
WatchdogSec=30
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Bu dosyayı /etc/systemd/system/api.service konumuna yerleştirdim. WatchdogSec=30 ifadesi, systemd'nin watchdog ping'ini 30 saniye içinde beklemesi gerektiğini belirtir. Hizmet bu sürede check-in yapmazsa, yanıt vermez sayılır ve 5 saniye sonra yeniden başlatılır.
Servisin gerçekten ping göndermesi için Python kodunu şu şekilde değiştirdim:
import systemd.daemon
while True:
# do work
systemd.daemon.notify('WATCHDOG=1')
time.sleep(25) # ping every 25s, well under 30s limit
Bu, watchdog'ın mutlu kalmasını sağlar. Döngü bloke olursa—örneğin, kilitlenmiş bir DB sorgusu nedeniyle—ping gönderimi durur ve systemd hizmeti yeniden başlatır.
Watchdog Durumunu Doğrulama
sudo systemctl daemon-reload komutuyla yeniden yükledikten ve hizmeti yeniden başlattıktan sonra, watchdog durumunu şu komutla kontrol ederim:
$ systemctl status api.service
● api.service - Internal API Service
Loaded: loaded (/etc/systemd/system/api.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2024-05-20 10:15:00 UTC; 2h 30min ago
Main PID: 1234 (api-server)
Tasks: 8 (limit: 4915)
Memory: 120.5M
CGroup: /system.slice/api.service
└─1234 /usr/local/bin/api-server
May 20 10:15:00 server systemd[1]: Started Internal API Service.
May 20 10:15:00 server systemd[1]: Watchdog enabled on api.service.
Watchdog enabled on api.service satırı, watchdog’un aktif olduğunu doğrular. Hizmet donar ise şu satırları görürsünüz:
May 20 12:45:22 server systemd[1]: api.service: Watchdog timeout!
May 20 12:45:22 server systemd[1]: api.service: Main process exited, code=killed, status=5/TRAP
May 20 12:45:22 server systemd[1]: api.service: Unit entered failed state.
May 20 12:45:27 server systemd[1]: api.service: Started Internal API Service.
Bu otomatik kurtarma, WatchdogSec’in değerli olduğu özelliktir—manuel müdahale gerektirmeden MTTR’yi azaltır.
WatchdogSec Kullanmaması Gereken Durumlar
Fork veya kısa ömürlü çocuk süreçler oluşturan hizmetlerde (örneğin bazı cron benzeri çalışanlar) WatchdogSec'i etkinleştiren takımlar gördüm. Ebeveyn süreç hızlıca çıkıyorsa ancak çocuk süreçler hâlâ çalışmaya devam ediyorsa, watchdog yanlışlıkla tetiklenebilir. Bu durumlarda, hizmeti ebeveyn sürecin canlı kalmasını sağlayacak şekilde yeniden yapılandırmak ya da farklı bir izleme yaklaşımı kullanmak gerekir.
Ayrıca, WatchdogSec'i çok düşük ayarlamaktan kaçının. Normalde beklenen en uzun işlem döngüsünün 2-3 katıyla başlarım. Örneğin, bir hizmet genellikle 10 saniyeden kısa sürede yanıt veriyorsa, 30 saniye güvenli bir ayardır. Çok kısa ayarlanması, geçici artışlar sırasında gereksiz yeniden başlatmalara yol açar.
Bu bölüm metnini Türkçeye çevir. Anlam aynı kalsın. İngilizce cümle bırakma.
Diğer systemd Özellikleriyle Birleştirme
WatchdogSec'i genellikle şunlarla birlikte kullanırım:
Restart=on-failure, yeniden başlatmaların sadece gerçek hatalar olduğunda gerçekleşmesini sağlamak içinStartLimitIntervalSecveStartLimitBurst, hizmet başlangıçta hemen çökerse yeniden başlatma döngülerini önlemek için- Kritik altyapı için
FailureAction=reboot(dikkatli kullanın)
Benim systemd-nspawn ve seccomp ile tehlikeli komutları izole etme konulu yazımda da belirttiğim gibi, bu mekanizmaları katmanlayarak dayanıklılık oluştururuz.
Gerçek Dünya Etkisi
Ödeme ağ geçidi hizmetimize WatchdogSec ekledikten sonra, "hizmet yanıt vermiyor" olayları için PagerDuty uyarılarında %70'lik bir düşüş gözlemledik. Hizmet, donmalarına yol açan hatalarla hâlâ karşılaşıyordu, ancak systemd onu saniyeler içinde geri getiriyordu—kullanıcılar fark etmeden önce genellikle.
Bu, kök nedenin çözümü değil, ancak sağlam bir güven ağdır. Bir devre kesici gibi düşünün: aşırı yükü önlemez, ama zincirin yayılmasını durdurur.
systemd hizmetleri çalıştırıyorsanız ve daha iyi kendini onarabilme yeteneği istiyorsanız, en kritik hizmetlerinizde WatchdogSec'ten başlayın. Test etmek için sürece SIGSTOP sinyali gönderin ve systemd'nin onu nasıl geri getirdiğini izleyin.