현상
Nginx를 프록시 서버로 사용하고 있는데 간헐적으로 504 Timeout이 발생하는 것을 확인했다.
<html>
<head><title>504 Gateway Time-out</title></head>
<body>
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx</center>
</body>
</html>
원인을 확인하고 해결 방법……이라고 하기 보다는 현상 해소와 관련된 설정값을 적어둔다.
원인
관련 로그는 niginx 로그의 proxy-error.log에서 찾을 수 있다.
2024/10/17 08:06:01 [error] 1345049#1345049: *1213 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 10.100.100.100, server: an.internal.example.biz, request: "POST /services HTTP/1.1", upstream: "http://127.0.0.1:8030/services", host: "an.internal.example.biz"
이 로그는 프록시 서버에서 업스트림, 즉 백엔드 서버에서의 응답 헤더를 읽으려던 과정에서 타임 아웃이 발생했다는 뜻이다. 프록시 서버와 업스트림 간의 연결 설정이 너무 짧게 설정되어 있거나, 업스트림이 요청에 응답하는 데 너무 오래 걸리는 경우일 수 있다.
로그를 해석하면 10.100.100.10 클라이언트에서 an.internal.example.biz 서버의 /services 쪽으로 HTTP/1.1 요청이 왔지만 http://127.0.0.1:8030/services 업스트림의 응답이 늦어 타임아웃이 발생했다는 의미이다.
타임아웃 관련 설정
근본적으로는 업스트림이 요청에 응답하기까지의 시간을 개선해야 한다.
그러나 타임아웃까지의 시간이 너무 짧게 설정되어 있는 상태가 맞다면 Nginx 상에서의 timeout 관련 설정을 조정할 필요가 있다.
Nginx에서 사용하는 Timeout 관련 설정이 굉장히 많은데, 이 글에서는 현상 해소에 사용한 값만 적어둔다.
# /etc/nginx/sites-available/was.conf
server {
listen 8080;
server_name an.internal.example.biz;
access_log /var/log/nginx/reverse-access.log;
error_log /var/log/nginx/reverse-error.log;
location /services {
proxy_pass http://localhost:8030/services;
proxy_send_timeout 600;
proxy_read_timeout 600;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
proxy_send_timeout
업스트림 서버에 요청을 전송하기 위한 시간 초과 설정이다. 전체 요청 전송이 아니라 연속적인 두 번의 쓰기 작업에서만 적용된다. 업스트림 서버가 이 시간 내에 아무것도 수신하지 못하면 연결이 닫힌다. 초 단위로 설정할 수 있고 기본값은 60초이다. http, server, location 블록에 설정할 수 있다.
proxy_read_timeout
업스트림 서버에서 응답을 읽는 것에 대한 시간 초과 설정이다. 전체 응답 전송이 아닌 연속적인 두 번의 읽기 작업 사이에서만 적용된다. 업스트림 서버가 이 시간 내에 아무것도 전송하지 않으면 연결이 닫힌다. 초 단위로 설정할 수 있고 기본값은 60초이다. http, server, location 블럭에 설정할 수 있다.
proxy_connect_timeout
프록시 서버와의 연결을 설정하기 위한 시간 초과 설정이다. 기본값은 60초인데, 일반적으로 75초를 초과할 수 없다. http, server, location 블록에 설정할 수 있다.
참고 문서
https://nginx.org/en/docs/http/ngx_http_proxy_module.html