case-503

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.

  • Caddy
  • reverse proxy
  • health check
  • 503

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 available benzeri 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_uri olarak 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.

Kurum ve ortam bilgileri çıkarılmış, komut ve yapılandırma örnekleri genelleştirilmiştir. Kendi ortamınızda önce test edin.

Bu not, sitedeki vaka dosyalarından birinin uzun hâlidir. Taslağı Claude ile hazırlandı.

ls ~/notlar

Diğer notlar

Tüm notlar

Bir altyapı sorusu, proje ya da rota önerisi mi var?

En hızlı yol e-posta. Seyahatteysem bir sonraki Wi-Fi'da dönerim.

E-posta gönder