- Published on
504 Gateway Time-out 에러 해결을 통한 개인적인 정리
- Authors

- Name
- 김민석
Introduction
상황
배포한 파일 업로드 기능에서 오류가 발생했다.
파일을 업로드하면 서버에서 예상한 응답을 받지 못하고 504 Gateway Timeout 오류가 나타났다 .
이 문제는 Spring Boot 애플리케이션과 Nginx 리버스 프록시를 이용한 배포 환경에서 발생했고,
특히 요청 처리에 시간이 오래 걸리는 상황에서 타임아웃 문제가 빈번히 나타난 것이다 .
문제

이 문제는 사용자가 파일을 업로드하는 중에 발생했기 때문에 큰 영향을 미칠 수 있었다.
504 Gateway Timeout 오류는 서버가 요청을 처리하는 데 너무 오래 걸릴 때 발생하는 오류로,
클라이언트가 오랜 시간 동안 기다리다가 서버와의 연결이 끊어진다는 것을 의미한다.
따라서 이 문제를 해결하지 않으면 애플리케이션이 제대로 동작을 하지 않는다는 문제점이 생긴다.
원인
배포 후 파일을 업로드하자마자 에러 메시지를 확인했다.
또한, 개발자 모드에서 로그를 통해 타임아웃 문제가 발생했음을 확인할 수 있었다.
특히, 504 Gateway Timeout 메시지와 함께 Nginx 로그에는 프로세스가 계속 재시작되는 현상이
나타났고, Spring Boot 로그에서는 요청이 완료되지 못하는 현상을 감지했다.
Nginx와 springboot 로그를 확인하여 이쪽은 문제가 없다는 걸 알 수 있었다.

- Nginx 에러 로그.

- springboot 로그.
또 다른 에러, HTTP method names must be tokens

HTTP 요청의 메서드 이름에 유효하지 않은 문자가 포함되어 있을 때 발생하는 에러였다.
로그에 나온 내용처럼 Invalid character found in method name이라는 메시지가 뜨는 이유는
클라이언트에서 잘못된 HTTP 요청이 서버로 전달된 경우일 가능성이 크다.
이런 문제는 일반적으로 아래와 같은 상황에서 발생할 수 있었다.
- 클라이언트가 잘못된 형식의 요청을 보낼 때.
- 프록시나 로드 밸런서가 잘못된 요청을 전달하는 경우.
- 네트워크 연결 문제로 인해 데이터가 손상되었을 때.
나의 해결 방법
- 클라이언트 코드에서 올바른 HTTP 메서드를 사용하고 있는지 확인했다.
- 예를 들어,
POST,GET과 같은 HTTP 메서드 이름이 정확히 지정되었는지 체크하였다.
location / {
# GET, POST, PUT 등 정상적인 HTTP 메소드가 아닌 경우 차단
if ($request_method !~ ^(GET|POST|HEAD|PUT|DELETE|OPTIONS)$) {
return 444;
}
// ... 생략
- 서버의 보안 그룹에서의 인바운드 규칙 확인했다.
- 이 문제를 해결하기 위해, 서버의 보안 그룹에서
8080 포트에 대한 인바운드 규칙을 제거하여 외부에서 직접 8080 포트로 접근할 수 없도록 설정했다. - 이를 통해, 8080 포트를 통한 불필요한 외부 접근을 차단하고, 보안성을 높이기 위한 조치를 취했다.

해결
컨트롤러에서 Thread.sleep(35초) 테스트
문제를 재현하고자 컨트롤러에 테스트 API를 추가하여 Thread.sleep(35 * 1000);으로 지연을 주고 로컬과 Nginx 환경에서 각각 테스트를 진행했다.
- 이를 통해 지연이 발생할 때 타임아웃이 발생하는 것을 확인할 수 있었다.
@RestController
public class TimeoutTestController {
@GetMapping("/test-timeout")
public ResponseEntity<String> testTimeout() {
try {
// 35초간 대기
Thread.sleep(35000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return ResponseEntity.ok("Response after 35 seconds");
}
}
Nginx 및 Spring Boot 타임아웃 설정
proxy_read_timeout 설정을 통해 타임아웃 문제를 해결 할 수 있었다.
504 Gateway Timeout 오류를 해결하려면 주로 proxy_read_timeout 시간을 늘려서 Nginx가 백엔드 서버로부터의 응답을 더 오래 기다리도록 설정할 수 있다.
http {
server {
...
location / {
proxy_pass http://backend-server;
proxy_connect_timeout 60s; # 서버 연결 대기 시간
proxy_read_timeout 120s; # 응답 대기 시간, 120초로 설정
proxy_send_timeout 60s; # 요청 전송 시간
}
}
}
proxy_connect_timeout이나 proxy_send_timeout 값도 필요에 따라 조정할 수 있지만, 응답 지연 문제 해결에는 proxy_read_timeout이 가장 중요한 설정이다.
각각에 대한 추가 설명
- proxy_connect_timeout
- proxy_read_timeout
- proxy_send_timeout
proxy_connect_timeout
- Nginx가 서버에
처음 연결을 시도할 때까지 기다리는 최대 시간이다. 작동 방식:Nginx는 클라이언트 요청을 처리할 서버(예: Spring Boot 애플리케이션)로 연결을 시도한다.- 이 과정에서 Nginx는
proxy_connect_timeout에 설정된 시간 동안 연결이 수립될 때까지 기다린다.
- 이 과정에서 Nginx는
용도:서버의 응답이 느리거나 서버 연결이 불안정할 때 사용된다. 이 값이 지나치게 짧으면 연결이 수립되기 전에 요청이 타임아웃될 수 있다.ex):proxy_connect_timeout 60s;로 설정되었다면, Nginx는 60초 동안 서버로의 연결을 시도한다. 60초 이내에 연결이 수립되지 않으면 Nginx는 연결을 포기하고 오류를 반환하게 되는 것이다.
proxy_read_timeout
- Nginx가 서버의 첫 응답을 기다릴 최대 시간을 설정해, 응답 지연 시 오류를 방지하는 설정이다.
작동 방식:Nginx는 서버로 요청을 전송한 후, 응답의 첫 번째가 도착하기까지proxy_read_timeout에 설정된 시간만큼 기다린다.용도:서버에서 작업 처리에 시간이 오래 걸리는 경우에 필요하다. 예를 들어, 서버에서 긴 시간 동안 데이터를 처리할때 시간이 길어질 수 있다.- 설정된 시간 내에 응답이 도착하지 않으면 Nginx는 타임아웃으로 요청을 종료하고 504 Gateway Timeout 오류를 반환한다.
ex):proxy_read_timeout 60s;로 설정되어 있으면, Nginx는 서버가 60초 이내에 첫 번째 응답을 보내기를 기다린다. 그렇지 않으면 요청이 타임아웃 되는 것이다.
proxy_send_timeout
- Nginx가 서버로
데이터를 전송할 때, 데이터 전송이 완료될 때까지 기다리는 시간이다. 작동 방식:클라이언트가 Nginx를 통해 서버로 큰 양의 데이터를 전송할 때, 전송이 완료되기까지proxy_send_timeout에 설정된 시간만큼 대기한다.용도:Nginx가 클라이언트로부터 큰 파일을 받아 서버로 보내야 하는 경우 이 설정이 유용하다. 지정된 시간 안에 데이터가 전송되지 않으면 타임아웃이 발생하고, Nginx는 연결을 끊는다.ex):proxy_send_timeout 60s;로 설정되어 있다면, Nginx는 60초 동안 데이터를 서버로 전송을 시도한다. 전송이 완료되지 않으면 요청이 중단된다.
로컬 환경에서 테스트하기 (성공)
- 144초 동안 대기한 후에 응답이 오는지 확인했다.

로컬에서 144초 후에 응답이 정상적으로 도착하면서,
로컬 서버는 이 시간 동안 문제 없이 응답을 제공할 수 있다는 것을 의미했다.
그렇게 하면 왜 해결되는지
- 이 문제는
로컬 환경에서는 해결되었지만,서버 환경에서는 해결되지 않았다.로컬에서는 예상한 대로 동작했으나, 서버에서는 여전히 동일한 에러가 발생하여 추가적인 조치가 필요했다. - 로컬에서는 정상적으로 동작했지만, 서버 환경에서 동일한 문제를 해결하기 위해 서버와 클라이언트 간의 응답 대기 시간인
proxy_read_timeout설정을 조정했다. - 이를 통해
Nginx가 서버로부터 충분한 시간이 지나더라도 응답을 기다리게 함으로써 서버로부터 응답이 올 때까지 요청이 끊기지 않도록 설정 했다. - 최종적으로, 서버 환경에서도 문제가 해결되어 정상적인 파일 업로드와 요청 처리가 가능해졌다는 것이다.
결말
배포 된 서버 환경 (성공)

얼마나 개선되었는지
proxy_read_timeout설정을 조정한 후에는 타임아웃 오류가 더 이상 발생하지 않았으며, 업로드된 파일이 정상적으로 처리되었다.- 이를 통해 사용자가 파일을 업로드하는 과정에서 발생하던 오류가 크게 줄어들었다는 것이다.
배우는 것은 무엇인지
- 이번 문제 해결을 통해 서버 타임아웃과 관련된 설정의 중요성을 배우게 되었다.
Nginx와Spring Boot의 타임아웃 설정을 적절히 조정하는 것만으로도 시스템을 개선할 수 있음을 깨달았다.- 또한, 배포 환경에서 발생하는 문제를 해결하기 위해
로깅을 활용하는 방법과,설정을 하나씩 변경하며 테스트하는 방법의 중요성을 다시 한 번 실감했다.
다른 방법은 없었는지
- 다른 방법으로는 파일 업로드 처리를 백그라운드에서 진행하는 비동기 방식을 생각해볼 수 있었다.
- 이 방법을 사용하면 서버가 파일 처리를 뒤에서 진행하고, 클라이언트는 바로 응답을 받아 타임아웃 문제가 줄어들 수 있게 할 수 있지 않을까 생각해봤다.
- 하지만, 이 방법은 코드 구조를 많이 변경해야 해서, 이번에는 간단한 타임아웃 시간 조정 방법을 선택했다.