Üretimde “servisi restart ettim, 10 saniye 502 yedik” cümlesi çoğu zaman normalleştirilir. Oysa servis çok kritikse (auth, gateway, queue consumer control-plane gibi) restart etkisini sıfıra yakın bir yere çekmek mümkündür.
systemd’nin socket activation özelliği, “portu dinleme” işini servis prosesinden ayırır. Böylece servis prosesini yeniden başlatırken, dinleme soketi ayakta kalır ve bağlantı kabulü kesilmez.
Socket activation ne çözer?
Socket activation şu problemleri küçültür:
- Restart sırasında portun kısa süreli kapanması
- Orkestrasyon (deploy) dalgasında LB health-check flap’i
- “Servis çok hızlı açılmadı” kaynaklı cold-start etkileri
Ön koşullar
- Linux + systemd (çoğu modern distro)
- Servisinizin
LISTEN_FDS/LISTEN_PIDüzerinden systemd socket’ini kullanabilmesi- Birçok dil/runtime bunu destekler (Go, Rust, Node ekosisteminde wrapper’lar var)
- Kendi servisiniz desteklemiyorsa, basit bir “socket-accept” wrapper ile de çözülebilir
Bu yazıda odak “mekanizma” olduğu için, örnekleri minimal tutacağım.
Mimari: .socket + .service
Model:
myapp.socketportu dinler- Bağlantı geldiğinde
myapp.servicebaşlar (veya zaten çalışıyorsa FD’yi kullanır)
1) Socket unit örneği
/etc/systemd/system/myapp.socket:
[Unit]
Description=myapp socket
[Socket]
ListenStream=127.0.0.1:8080
NoDelay=true
ReusePort=false
[Install]
WantedBy=sockets.target
Notlar:
ListenStreamadresi güvenlik modelinize göre değişir (0.0.0.0 açacaksanız firewall şart).ReusePortçoğu senaryoda istemeden karmaşa üretir; önce kapalı tutun.
2) Service unit örneği
/etc/systemd/system/myapp.service:
[Unit]
Description=myapp service
After=network.target
Requires=myapp.socket
[Service]
Type=simple
ExecStart=/usr/local/bin/myapp
Restart=on-failure
RestartSec=2
# Hardening (minimum)
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
[Install]
WantedBy=multi-user.target
Çalıştırma
sudo systemctl daemon-reload
sudo systemctl enable --now myapp.socket
sudo systemctl status myapp.socket
Servisi manuel başlatmak zorunda değilsiniz; ilk bağlantıyla tetiklenebilir. Ama “her zaman sıcak” tutmak istiyorsanız myapp.service’i de enable edebilirsiniz.
Zero-downtime restart runbook
Hedef: restart sırasında port düşmesin, LB health-check bozulmasın, kullanıcı hatası üretmeyelim.
- Hazırlık
-
myapp.socketenabled ve active mı? - LB health-check hedefi doğru mu? (ör.
localhost+ sidecar varsa dikkat)
- Restart
sudo systemctl restart myapp.service
- Doğrulama
-
ss -lntp | grep 8080ile port dinlemesi devam ediyor mu? - Uygulama loglarında “listening failed” var mı?
- Hata oranı / p95 deploy sırasında yükseldi mi?
Operasyonel guardrail’ler
Ben prod’da şunları standartlaştırmayı seviyorum:
StartLimitIntervalSec/StartLimitBurst: crash-loop’un gürültüsünü kontrol et- Health-check endpoint’i: “hazır” olmadan 200 dönme
- Restart dalgası: canary → pilot → genelleme
Sonuç
systemd socket activation, “restart = kısa kesinti” refleksini kıran güçlü bir mekanizmadır. Doğru kurulduğunda, deploy dalgalarında LB flap’ini azaltır ve incident ihtimalini belirgin düşürür. Bunu graceful shutdown, ölçüm ve kademeli rollout ile birleştirdiğinizde; servisin restart’ı operasyonel olarak “rutin” hale gelir.