서버 운영
서버 배포 후 502와 504를 구분해서 본 비교 메모
Nginx 앞단에서 502와 504가 보일 때 같은 장애로 묶지 않고 upstream 상태와 timeout을 나눠 확인한 메모입니다.
같은 흰 화면처럼 보여도 원인이 달랐다
배포 직후 브라우저에는 그냥 에러 화면만 보였다. 처음에는 502든 504든 서버가 죽은 상태라고 뭉뚱그려 생각했다. 그런데 로그를 보니 둘은 확인해야 할 방향이 달랐다. 이 차이를 모르면 엉뚱한 설정만 만지게 된다.
제가 겪은 상황은 Node 앱을 systemd로 띄우고, Nginx가 앞에서 프록시하는 구조였다.
502를 봤을 때 먼저 본 것
502 Bad Gateway는 Nginx가 upstream과 제대로 대화하지 못했을 때 자주 만났다. 앱 프로세스가 죽었거나, 포트가 다르거나, 소켓 권한이 맞지 않는 경우가 있었다.
sudo systemctl status app.service
sudo journalctl -u app.service -n 80 --no-pager
ss -ltnp | grep 3000
한 번은 .env의 포트를 3001로 바꿔 놓고 Nginx는 계속 3000으로 보내고 있었다. 앱은 정상 실행 중이라 더 헷갈렸다. 이때부터는 프로세스 상태와 실제 listen 포트를 같이 본다.
504를 봤을 때 먼저 본 것
504 Gateway Timeout은 upstream이 아예 없다는 느낌보다, 응답이 제한 시간 안에 돌아오지 않는 쪽에 가까웠다. 외부 API를 기다리거나 DB 쿼리가 길어진 경우가 있었다.
sudo tail -n 50 /var/log/nginx/error.log
sudo journalctl -u app.service --since "5 minutes ago"
Nginx timeout을 무작정 늘리기 전에 앱 로그에서 어느 요청이 오래 걸리는지 확인했다. timeout을 늘리면 화면의 에러는 늦게 보일 수 있지만, 느린 원인이 사라지는 건 아니다.
비교해서 보는 기준
| 상태 코드 | 먼저 의심한 것 | 확인 명령 |
|---|---|---|
| 502 | 앱 종료, 포트 불일치, upstream 연결 실패 | systemctl status, ss -ltnp |
| 504 | 앱 응답 지연, DB/API 대기, timeout 부족 | error.log, 앱 요청 로그 |
둘 다 Nginx 화면으로 보이지만, 502는 연결 자체를 먼저 보고 504는 처리 시간을 먼저 본다.
제가 바꾼 배포 확인 순서
배포 후에는 브라우저만 새로고침하지 않고 아래 순서로 확인한다.
curl -I http://127.0.0.1:3000
curl -I https://example.com
sudo journalctl -u app.service -n 30 --no-pager
sudo tail -n 30 /var/log/nginx/error.log
내부 앱은 정상인데 외부 도메인만 실패하면 Nginx 설정을 본다. 내부 앱부터 실패하면 애플리케이션 로그를 먼저 본다.
끝에 적어 둔 한 줄
502와 504를 같은 말로 부르면 디버깅 순서가 흐려진다. 상태 코드는 해결책을 바로 알려 주지는 않지만, 어디부터 볼지 정하는 이정표 정도는 된다.