Troubleshooting 배포 중 업로드 중단 - 100-hours-a-week/KTB4-2nd-Cloud GitHub Wiki

배포 중 사진 업로드 중단

2026-09-29

🐞 에러 내용

Backend 로그 수집 설정을 반영하려고 Production 배포를 실행했는데, 그때 팀원이 여행 109에 사진을 올리고 있었습니다. 14시 4분에 Discord로 Alarm이 왔습니다.

ALARM | yeodam-v1-nginx-5xx
Threshold Crossed: 18 >= 5

Nginx 로그를 보니 마지막 사진 Batch 요청이 약 50MB를 보낸 뒤 143초 만에 502로 끝났습니다.

POST /api/trips/109/initial-attachments
status=502 request_length=50915370 request_time=143.370

바로 뒤에 Frontend와 Backend 요청도 잠깐 500, 502를 반환했습니다.

🔍 원인 분석

Nginx Error 로그에는 Backend 연결이 먼저 끊기고, 이어서 FE, BE 포트 모두 연결이 거부된 기록이 있었습니다.

upstream prematurely closed connection while reading response header from upstream
connect() failed (111: Connection refused) while connecting to upstream

같은 시각에 배포가 FE, BE 컨테이너를 교체하고 있었습니다. 새 Backend는 14시 4분 12초부터 기동 로그를 남겼고, 로그의 release도 배포한 이미지 커밋과 같았습니다.

배포한 변경 내용이 문제가 아니라, 처리 중인 요청이 있는 상태에서 컨테이너를 교체한 게 원인이었습니다.

문제의 요청 전까지 10개 Batch는 모두 204로 끝났습니다. 끊긴 마지막 Batch를 배포 뒤 다시 보내자 409가 돌아왔습니다. 서버에는 일부 반영됐는데 응답만 끊겼을 가능성이 있어서, 여행 109의 저장 상태는 별도로 확인할 항목으로 남겼습니다.

✅ 해결 방법

배포가 끝난 뒤 외부에서 Backend health가 UP인 것과, 새 로그가 CloudWatch에 들어오는 것을 확인했습니다. 서비스는 바로 돌아왔습니다.

같은 일을 막으려면 배포가 이 순서로 진행돼야 합니다.

flowchart LR
  A["신규 업로드 차단"] --> B["진행 중인 업로드<br/>끝날 때까지 대기"]
  A --> C["Worker 현재 작업<br/>끝날 때까지 대기"]
  B --> D["App, Worker 교체"]
  C --> D
  D --> E["검증 후<br/>업로드 재개"]
Loading

CD 설계에 이미 이 Drain 순서가 있었지만, Backend에 활성 업로드 수를 알려주는 방법이 아직 없어 배포에 연결하지 못한 상태였습니다. Backend 팀과 조회 방식을 정한 뒤 배포 절차에 넣기로 했고, 그전까지는 진행 중인 업로드가 없는 시간을 확인하고 배포합니다.

회고

배포 워크플로가 성공하는 것만 확인했고, 배포 중에 사용자 요청이 안전한지는 검증하지 않았습니다. 설계에서 나중으로 미뤄둔 Drain이 운영에 꼭 필요한 조건이라는 걸 실제 요청이 끊기고 나서 확인했습니다.

그래도 Nginx 5xx Alarm이 바로 울려서 영향 범위를 빠르게 좁힐 수 있었습니다.

⚠️ **GitHub.com Fallback** ⚠️