-
[Nginx] Proxy 상황에서 Connection 유지하기Backend 2021. 12. 13. 22:48반응형
예전에 Connection 헤더 문제로 삽질 했던걸로 최근에 또 삽질을 하게 돼서 이번에는 확실하게 정리를 하려고 한다.
3줄 요약
- Nginx는 upstream 서버로 proxy를 할 때 HTTP 버전을 1.0으로, Connection 헤더를 close로 변경해서 전달한다.
- Connection을 유지하기 위해서는 HTTP 버전은 1.1로, Connection 헤더는 없애주자.
- 관련 공식 문서: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version
문제 상황
서버에서 클라이언트로 일정 간격으로 데이터를 내려주어야 하는 상황이어서 Server Sent Event 엔드포인트를 개발 중이었다.
로컬에서 문제없이 작동하는 것을 확인하고 테스트 서버에 올려서 클라이언트와 연동을 하는데, 멀쩡히 작동하던 SSE를 클라이언트가 전달받지 못하는 문제가 발생했다.(정확히는 요청이 무한정 pending되는 상황)
서버쪽에서는 요청을 잘 전달받고, 응답도 정상적으로 보내주는 것을 확인했다. 그러면 테스트 서버에서 리버스 프록시 용으로 설치해놓은 Nginx가 문제일 것이라는 생각이 들었다.
설정파일은 대략 다음과 같이 작성된 상태였다.
upstream server { server 127.0.0.1:8080; keepalive 32; } server { listen 80; server_name 127.0.0.1; location /api { proxy_pass http://server; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; } }
와이어샤크로 HTTP 요청을 확인해 보니 Client는 Nginx 서버에 정상적으로 Connection: keep-alive 헤더와 함께 요청을 보내는 것을 확인할 수 있었다.
그런데 Nginx 서버에서 API 서버로 이 요청을 프록시할 때 HTTP 버전을 1.0으로, Connection 헤더를 close로 바꿔서 보내는 것이었다.
문제의 원인
Nginx는 기본적으로 HTTP 요청을 upstream 서버로 프록시할 때 HTTP 버전을 1.0으로 바꿔서 보낸다. 이 과정에서 Connection 헤더도 close로 바꾸는 듯 하다.
구글링을 열심히 해 본 결과 HTTP/1.0에서는 커넥션을 유지하는 것이 기본이 아니다. 그래서 Connection: keep-alive라는 헤더가 필요하고, HTTP/1.1에서는 커넥션을 유지하는 것이 기본이기 때문에 이 헤더가 필요없다고 한다.
그리고 커넥션을 제어하는 이 Connection 헤더는 HTTP/2에서 금지되었다.
Nginx 공식문서에서는 keepalive 커넥션을 사용하기 위해서는 프록시 HTTP 버전을 1.1로 변경해야 한다고 권장한다.
문제의 해결
문제의 해결은 간단하다. 요청을 프록시할 때 HTTP 버전을 1.1로 명시해주고, Connection헤더를 없애주는 설정을 추가하는 것이다.
설정파일을 다음 두 라인을 추가해준다.
proxy_http_version 1.1;
proxy_set_header Connection "";upstream server { server 127.0.0.1:8080; keepalive 32; } server { listen 80; server_name 127.0.0.1; location /api { proxy_http_version 1.1; # <- proxy_set_header Connection ""; # <- proxy_pass http://server; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; } }
Nginx에서 API 서버로 HTTP/1.1 요청이 가는 것을 확인할 수 있었다.
References
반응형'Backend' 카테고리의 다른 글
[Docker] 개발용 데이터베이스 띄우기(MySQL, PostgreSQL, MongoDB) (0) 2022.03.27