Przejdź do treści głównej

Poradniki / Kody statusu HTTP wyjaśnione

502 Bad Gateway: co zepsuło się za proxy i jak to znaleźć

502 Bad Gateway oznacza, że proxy przed Twoją stroną poprosiło backend o odpowiedź i dostało coś nieprawidłowego, albo nic w ogóle. Proxy działa poprawnie; zgłasza, że to, co stoi za nim, nie działa, ulega awarii albo mówi w złym protokole.

Kto zwraca 502 i dlaczego

RFC 9110 definiuje 502 dla serwera działającego jako brama albo proxy, który otrzymał nieprawidłową odpowiedź od serwera wewnętrznego, z którym łączył się, próbując zrealizować żądanie. Każdy nowoczesny stos ma przynajmniej jeden taki skok: nginx albo Apache przed serwerem aplikacji, load balancer przed flotą, CDN przed Twoim serwerem źródłowym, albo wszystkie trzy.

Ta warstwowość jest kluczem do odczytania 502. Komponent, który odpowiedział, jest wystarczająco zdrowy, żeby wygenerować stronę błędu. Komponent za nim nie jest. Więc 502 zawsze dzieli Twój stos na działającą połowę i zepsutą połowę, a Twoim zadaniem jest ustalić, gdzie leży ta granica.

Jego sąsiedzi mówią coś węższego. 504 Gateway Timeout oznacza, że backend był osiągalny, ale za wolny. 500 oznacza, że sam backend uruchomił się i rzucił błąd. 502 oznacza, że backend dał złą odpowiedź albo żadnej. Pełne porównanie jest w przeglądzie 5xx.

Częste przyczyny

  • Proces backendu nie działa. Zawieszony serwer aplikacji, zatrzymana pula PHP-FPM, kontener, który się zakończył albo nie przeszedł kontroli zdrowia. Proxy łączy się z portem, na którym nikt nie nasłuchuje.
  • Backend uległ awarii w trakcie żądania. Zabicie przez brak pamięci albo błąd naruszenia ochrony pamięci zamyka połączenie, zanim nagłówki odpowiedzi zostaną skończone.
  • Zły adres albo port serwera wyżej w łańcuchu. Konfiguracja wskazująca stary port po zmianie, albo host, który już się nie rozwiązuje.
  • Niezgodność protokołów. Proxy mówi zwykłym HTTP do portu oczekującego TLS, albo odwrotnie. Bajty są nieparsowalne, więc proxy uznaje odpowiedź za nieprawidłową.
  • Zbyt duże nagłówki odpowiedzi. Zbyt duże ciasteczko albo niezwykle długi nagłówek przekracza bufor proxy, a odpowiedź zostaje odrzucona zamiast przekazana dalej.
  • Niezgodność keep-alive. Proxy ponownie wykorzystuje bezczynne połączenie, które backend już zamknął, co powoduje sporadyczne 502 przy skądinąd normalnym obciążeniu.
  • Restarty i wdrożenia. Każde okno, w którym stary proces już się zatrzymał, a nowy jeszcze nie przyjmuje połączeń.
  • Wszystkie backendy niezdrowe. Load balancer bez żadnego przechodzącego kontrolę członka nie ma gdzie wysłać żądania.

Czytanie logu proxy, które zwykle kończy dochodzenie

Kod statusu jest ogólny, ale linia w logu proxy jest konkretna. Przy nginx to komunikaty warte rozpoznania:

[error] connect() failed (111: Connection refused) while connecting to upstream,
        upstream: "http://127.0.0.1:8080/"

[error] upstream prematurely closed connection while reading response header
        from upstream

[error] recv() failed (104: Connection reset by peer) while reading response
        header from upstream

[error] upstream sent too big header while reading response header from upstream

[error] no live upstreams while connecting to upstream

Każdy wskazuje na coś innego:

  • connect() failed (111: Connection refused). Nic nie nasłuchuje na tym adresie i porcie. Backend jest zatrzymany, przypięty do innego interfejsu, albo na innym porcie, niż mówi konfiguracja.
  • upstream prematurely closed connection. Backend przyjął żądanie, a potem umarł albo się zawiesił, zanim skończył odpowiedź. Szukaj awarii, zabić przez brak pamięci albo timeoutów workerów wewnątrz aplikacji, nie przy nginx.
  • connection reset by peer. Podobne, ale połączenie zostało aktywnie zresetowane. Często zapora sieciowa pośrodku, albo backend, który zamknął połączenie z puli, które proxy wciąż uważało za otwarte.
  • upstream sent too big header. Problem z rozmiarem bufora w proxy, nie wina backendu. Odpowiedź jest prawidłowa, ale większa, niż proxy jest skonfigurowane, żeby pomieścić.
  • no live upstreams. Kontrole zdrowia oznaczyły każdy backend jako niedziałający.

Jak to naprawić

  1. Przetestuj backend bezpośrednio, omijając proxy. Z hosta proxy zażądaj samego adresu wyżej w łańcuchu:
    curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/
    200 tutaj przy 502 na publicznym URL-u oznacza, że wina leży w konfiguracji proxy albo w łączu między nimi. Odrzucone połączenie oznacza, że backend naprawdę nie działa.
  2. Sprawdź, czy backend działa i nasłuchuje na adresie, którego oczekuje proxy. Przypięcie do 127.0.0.1, gdy proxy łączy się z adresem kontenera, to częsta przyczyna.
  3. Przeczytaj log błędów proxy i dopasuj komunikat do powyższej listy, zanim zmienisz jakąkolwiek konfigurację.
  4. Potem przeczytaj log backendu. Awaria, zabicie przez brak pamięci albo timeout workera w tej samej sekundzie potwierdza przypadek "prematurely closed". Cisza wskazuje z powrotem na łączność.
  5. Zweryfikuj adres, port i schemat serwera wyżej w łańcuchu w konfiguracji proxy, zwłaszcza po migracji albo przebudowie kontenera.
  6. Podnieś bufory nagłówków proxy, jeśli log mówi, że nagłówek był za duży, i osobno ustal, dlaczego nagłówek urósł.
  7. Spraw, żeby wdrożenia się nakładały. Uruchom nowy proces, poczekaj, aż przejdzie kontrolę zdrowia, potem opróżnij i zatrzymaj stary. Aktualizacje toczone bramkowane kontrolą zdrowia całkowicie usuwają okno restartu, które powoduje 502 w czasie wdrożenia.

Wyłapanie 502, które trwa dwadzieścia sekund

502 z czasu wdrożenia i pętli awarii są krótkie. Backend restartuje się, zwraca błędy przez dwadzieścia sekund i wraca do działania, więc zanim ktokolwiek sprawdzi, strona jest w porządku i nie ma już na co patrzeć. Zaplanowana kontrola HTTP działająca nieprzerwanie zapisuje te okna ze znacznikami czasu, co zamienia "dziś rano było krótko dziwnie" w wzorzec, który możesz skorelować z wdrożeniami i restartami. 502 może też pochodzić z brzegu sieci CDN, a nie z Twojego serwera źródłowego, więc sprawdzanie z kilku regionów odróżnia globalną awarię backendu od problemu brzegowego dotykającego części Twojego ruchu, do czego służy rozproszony monitoring dostępności.

Sprawdź teraz

Uruchom darmowe sprawdzenie na swojej stronie - bez zakładania konta.

HTTP check

Monitoruj to na stałe

Otrzymasz powiadomienie w chwili awarii: HostTracker sprawdza z ponad 300 lokalizacji i powiadamia e-mailem, SMS-em, przez Slack, Telegram i nie tylko.

Funkcje HostTracker

Więcej w tej sekcji: Kody statusu HTTP wyjaśnione