Nginx 리버스 프록시 뒤 API가 504로 끊기는 이유
문제 발생
오래 걸리는 리포트 생성 API를 Nginx 뒤에 배치했더니, 백엔드는 정상적으로 처리를 계속하고 있는데도 클라이언트에는 60초 근처에서 504 Gateway Timeout이 반환됐습니다.
원인 분석
Nginx는 백엔드(upstream)로부터 응답을 기다리는 시간에 기본 제한을 두고 있습니다. 대표적으로 proxy_read_timeout(응답 데이터를 읽는 간격의 제한, 기본값 60초)이 있습니다. 백엔드가 이 시간 안에 아무 데이터도 보내지 않으면, Nginx는 백엔드가 죽었거나 응답 불가 상태라고 판단하고 클라이언트에 504를 반환한 뒤 연결을 끊습니다. 이때 백엔드 프로세스 자체는 계속 살아서 작업을 이어가고 있을 수 있습니다 — 그저 Nginx가 먼저 포기하고 끊은 것입니다.
관련된 타임아웃 설정이 여러 개 있어 헷갈리기 쉽습니다.
proxy_connect_timeout: Nginx가 백엔드와 연결을 맺는 데 걸리는 시간 제한proxy_send_timeout: Nginx가 백엔드로 요청을 보내는 간격의 제한proxy_read_timeout: 백엔드로부터 응답을 받는 간격의 제한 — 오래 걸리는 API에서 가장 자주 문제가 되는 값
해결 방안
- 실제로 오래 걸리는 것이 정상인 엔드포인트라면, 해당
location블록에서만 타임아웃을 늘립니다 — 전역으로 늘리면 정말 멈춘 백엔드를 감지하는 시간도 함께 늘어나 장애 감지가 느려집니다.
location /api/reports/ {
proxy_pass http://backend;
proxy_read_timeout 300s; # 이 경로만 5분까지 허용
}- 근본적으로는 60초 넘게 걸리는 동기 API 자체가 좋은 설계는 아닙니다 — 클라이언트도 그만큼 오래 연결을 유지해야 하고, 중간의 로드밸런서/방화벽 등 다른 구간의 타임아웃과도 계속 씨름해야 합니다. 가능하면 작업을 비동기 큐에 넣고 즉시 202 응답을 반환한 뒤, 클라이언트가 별도 상태 조회 엔드포인트로 완료 여부를 폴링하거나 웹소켓/SSE로 완료를 통지받는 구조로 바꾸는 것이 더 견고합니다.
- 타임아웃을 조정했다면 반드시 실제로 오래 걸리는 요청과 정상적으로 멈춘(hang) 요청 둘 다로 테스트해, 진짜 장애 상황에서 감지가 너무 늦어지지 않는지 확인합니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.