GrepBoard/매뉴얼
47 편 ·

Nginx 502 Bad Gateway — 오류 로그 문구로 원인 가르기

·Ubuntu 24.04.5 · Nginx 1.24.0 · Python 3.12 (시험용 백엔드)·7 단계

502 는 접속 로그만으로는 원인을 알 수 없습니다. error.log 의 문구 네 가지를 재현해 원인과 확인 명령을 짝지었고, 504 와도 구분합니다.

접속 로그의 502 는 결과만 알려 주고, 이유는 error.log 의 문구에 있습니다. 아래 줄은 Nginx 를 포트 18502 로 띄우고 백엔드를 일부러 망가뜨려 얻은 실제 로그이며, 길이를 줄이려고 앞의 시각·PID 와 중간의 client:·server: 는 … 로 줄였습니다. 5xx 를 내는 경로를 세는 방법은 이 글에 있습니다.

[1] 502 시각 부근의 error.log 를 봅니다. 접속 로그의 시각과 request: 의 경로로 짝을 맞춥니다. 파일 위치는 nginx -T 로 확인합니다.

console
# nginx -T 2>/dev/null | grep error_log# tail -n 20 /var/log/nginx/error.log

[2] connect() failed (111: Connection refused) while connecting to upstream 이면 그 주소·포트에서 듣는 프로세스가 없습니다. 로그의 upstream: 값을 ss 로 확인합니다. 헤더만 나오면 백엔드가 안 떠 있는 것입니다.

console
… [error] … *1 connect() failed (111: Connection refused) while connecting to upstream, … request: "GET /refused/ HTTP/1.1", upstream: "http://127.0.0.1:18591/", …$ curl -i http://127.0.0.1:18502/refused/HTTP/1.1 502 Bad Gateway# ss -tlnp 'sport = :18591'State Recv-Q Send-Q Local Address:Port Peer Address:Port Process

[3] upstream prematurely closed connection while reading response header from upstream 이면 연결은 됐지만 백엔드가 응답 헤더를 보내기 전에 끊었습니다. 포트는 열려 있어 ss 에는 나오므로, 같은 시각의 백엔드 로그에서 충돌·재시작·메모리 부족 종료를 찾습니다.

console
… [error] … *3 upstream prematurely closed connection while reading response header from upstream, … request: "GET /closed/ HTTP/1.1", upstream: "http://127.0.0.1:18593/", …# ss -tlnp 'sport = :18593'State Recv-Q Send-Q Local Address:Port Peer Address:Port ProcessLISTEN 0 5 127.0.0.1:18593 0.0.0.0:* users:(("python3",pid=48599,fd=3))

[4] no live upstreams while connecting to upstream 이면 upstream 블록의 서버가 모두 실패 상태라 Nginx 가 연결을 시도하지도 않았습니다. 아래는 서버 둘이 다 죽은 풀의 첫 요청(서버별 connect() failed)과 곧이은 둘째 요청입니다.

console
… [error] … *7 connect() failed (111: Connection refused) while connecting to upstream, … upstream: "http://127.0.0.1:18591/", …… [error] … *7 connect() failed (111: Connection refused) while connecting to upstream, … upstream: "http://127.0.0.1:18592/", …… [error] … *12 no live upstreams while connecting to upstream, … request: "GET /pool/ HTTP/1.1", upstream: "http://dead_pool/", …

[5] upstream timed out (110: Connection timed out) 은 502 가 아니라 504 Gateway Time-out 입니다. 백엔드가 살아 있고 답이 느린 경우이므로, proxy_read_timeout 을 늘리기 전에 백엔드가 왜 느린지 먼저 봅니다.

console
… [error] … *5 upstream timed out (110: Connection timed out) while reading response header from upstream, … request: "GET /slow/ HTTP/1.1", upstream: "http://127.0.0.1:18594/", …$ curl -i http://127.0.0.1:18502/slow/HTTP/1.1 504 Gateway Time-out

[6] proxy_pass https:// 로 평문 HTTP 백엔드에 붙으면 502 와 함께 아래 문구가 납니다. proxy_pass 의 스킴을 백엔드가 쓰는 쪽에 맞춥니다.

console
… [error] … *10 SSL_do_handshake() failed (SSL: error:0A00010B:SSL routines::wrong version number) while SSL handshaking to upstream, … upstream: "https://127.0.0.1:18595/", …

[7] 문구별로 정리하면 아래와 같습니다.

문구상태확인할 것
connect() failed (111: Connection refused)502ss -tlnp 'sport = :포트' 에 줄이 없음 · proxy_pass 주소·포트 · 백엔드 서비스
upstream prematurely closed connection502같은 시각 백엔드 로그 · ss 에는 나옴
no live upstreams502서버별 connect() failed 줄 · max_fails·fail_timeout
SSL_do_handshake() failed … wrong version number502proxy_pass 스킴(http://·https://)
upstream timed out (110: …)504백엔드 응답 지연 · proxy_read_timeout

Nginx 로그를 브라우저에서 바로 분석 ↗ — 아무것도 올라가지 않습니다.

#nginx#502#proxy