Backend 200 dönüyor, Caddy 503 veriyor: health check tuzağı
Uygulama sağlıklıyken Caddy'nin 503 döndürmesinin sık nedeni: health check'in beklediği durum kodu backend'in yanıtıyla uyuşmuyor. Teşhis ve çözüm.
Tarayıcıda 503 Service Unavailable, ama backend'e doğrudan curl atınca 200 OK. İlk refleks uygulamayı yeniden başlatmak olur; çoğu zaman sorun uygulamada değil, proxy'nin backend'i nasıl "sağlıklı" saydığındadır.
Belirti
- Backend'e proxy'yi atlayarak gidildiğinde her şey normal.
- Proxy üzerinden gelen her istek 503 ile dönüyor.
- Caddy loglarında
no upstreams availablebenzeri satırlar var.
Caddy'nin reverse_proxy modülü, aktif health check tanımlandığında backend'i düzenli aralıklarla yoklar. Yanıt beklenen kriteri karşılamazsa backend "sağlıksız" işaretlenir ve trafik ona gönderilmez. Sağlıklı backend kalmadığında istemci 503 görür. Uygulama ayakta olsa bile.
Neden olur?
Vakadaki durum şuydu: health check, backend'den 4xx bir yanıt bekleyecek şekilde yapılandırılmıştı. Muhtemelen bir zamanlar kontrol edilen uç nokta kimlik doğrulama istediği için 401 dönüyordu ve kural ona göre yazılmıştı. Sonradan uç nokta düzeltilip 200 dönmeye başlayınca kontrol başarısız oldu. Sağlıklı backend, proxy'nin gözünde "hasta" oldu.
Benzer sonuç veren diğer nedenler:
health_uriolarak verilen yol artık yok (404) ya da yönlendiriyor (301/302).- Health check uç noktası kimlik doğrulama istiyor.
health_timeout, uç noktanın gerçek yanıt süresinden kısa.- Health check farklı bir port ya da host başlığıyla gidiyor ve backend bunu reddediyor.
Teşhis
Önce proxy'nin gördüğünü kendiniz görün: health check ile aynı yolu, aynı başlıklarla çağırın.
# Backend'e doğrudan, health check'in kullandığı yolla
curl -i http://127.0.0.1:8080/health
# Durum kodunu ve süreyi tek satırda görmek için
curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' http://127.0.0.1:8080/health
Sonra Caddyfile'daki beklentiyle karşılaştırın:
example.com {
reverse_proxy 127.0.0.1:8080 {
health_uri /health
health_interval 10s
health_timeout 3s
health_status 4xx # ← backend artık 200 dönüyorsa her kontrol başarısız
}
}
Yönetim API'si açıksa upstream durumunu da sorgulayabilirsiniz:
curl -s localhost:2019/reverse_proxy/upstreams
Çözüm
Beklentiyi gerçek yanıta uydurun ve kontrolü bilinçli tasarlayın:
reverse_proxy 127.0.0.1:8080 {
health_uri /health
health_interval 10s
health_timeout 3s
health_status 2xx
}
İyi bir health check uç noktası için:
- Kimlik doğrulama istemesin, hafif olsun, yönlendirme yapmasın.
- Uygulamanın gerçekten iş yapabildiğini göstersin (ör. veritabanı bağlantısı), ama her kontrolde ağır sorgu çalıştırmasın.
- Beklenen durum kodu dokümante edilsin. Uç nokta değişirse proxy kuralı da aynı değişiklikte güncellensin.
Ders
503, "backend çöktü" demek değildir; "proxy'nin gönderebileceği sağlıklı backend yok" demektir. Önce bir bakalım: proxy'nin kontrol ettiği şeyi, proxy'nin gözünden kontrol edin.