ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Nginx Error: upstream prematurely closed connection while reading response header from upstream
    SystemEngineering/Web Application 2021. 7. 30. 21:18

    개요

    "백엔드에서 애플리케이션은 동작하는데 2분 정도가 지나면 502 Bad Gateway Error가 발생하면서 값을 프론트에서 수신받지 못합니다. Nginx 설정 값을 수정해 주세요"라는 문의가 들어왔다. 이게 과연 Nginx 문제일까?

    Nginx config 파일

    2분 정도에 연결이 끊긴다는 것은 timeout 설정 값을 확인해 볼 필요가 있다. upstream은 nodejs이고 proxy로 둔 nginx의 각 timeout은 300s이다.

    ... 생략
    upstream nodejs {
        server 127.0.0.1:8081;
        keepalive 1024;
    }
    
    server {
        listen 8080;
    
        # Increase proxy timeout
        # ------------------------
        proxy_read_timeout 300;
        proxy_connect_timeout 300;
        proxy_send_timeout 300;
        # ------------------------
    ... 생략

    위의 설정 값대로 작동되었다면, 300s정도의 connection이 유지되다가 nginx에서 연결을 끊어 버리는 것이 맞다. 하지만 2분 정도의 시간이 흘렀을 때 끊긴다는 것은 다른 설정 값이 적용되어 있다거나, default값이 120s라는 것일 것이다.

    Access Log와 Error Log

    Nginx Access Log

    log_format  main  '[$time_local] $remote_addr - $remote_user "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for" '
    '"$connection" "$request_time"';

    Access Log의 format은 위와 같이 설정되어 있다. $status와 제일 마지막인 $request_time에 주목해 보자.

    [25/May/2021:10:02:12 +0900] 172.31.25.55 - - "POST [path] HTTP/1.1" 502 157 "-" "-" "15.164.178.170" "14864" "120.004"
    ... 생략 ...
    [25/May/2021:14:51:43 +0900] 172.31.25.55 - - "POST [path] HTTP/1.1" 502 157 "-" "PostmanRuntime/7.26.8" "61.107.160.236" "109" "120.022"
    [25/May/2021:14:52:53 +0900] 172.31.25.55 - - "POST [path] HTTP/1.1" 502 157 "-" "-" "15.165.10.93" "129" "120.002"

    정말 120s에서 502 응답 코드를 반환하는 것을 확인할 수 있다.

    Nginx Error Log

    2021/05/25 14:51:43 [error] 27326#0: *109 upstream prematurely closed connection while reading response header from upstream, client: 172.31.25.55, server: , request: "POST [path] HTTP/1.1", upstream: "http://127.0.0.1:8081/[path]", host: "********"
    2021/05/25 14:52:53 [error] 27327#0: *129 upstream prematurely closed connection while reading response header from upstream, client: 172.31.25.55, server: , request: "POST [path] HTTP/1.1", upstream: "http://127.0.0.1:8081/[path]", host: "********"

    Error 내용을 보면 upstream에서 응답을 읽는 도중 연결을 끊어버렸다는 것이다. 즉, upstream인 noedjs에서 post에 대한 응답 값을 받기 이전에 연결을 끊었다는 의미이다.

    Nodejs 문서를 찾아보니 default timeout이 약 2분 (120s)라고 한다.

     

    HTTP | Node.js v6.17.1 Documentation

    HTTP# To use the HTTP server and client one must require('http'). The HTTP interfaces in Node.js are designed to support many features of the protocol which have been traditionally difficult to use. In particular, large, possibly chunk-encoded, messages. T

    nodejs.org

    router.post('[path]', (req, res) => {
    
        req.connection.setTimeout(1000000); //1000 seconds
      ...
    
    });

    위와 같이 설정하여 node의 Timeout을 증가할 수 있다. 결론은, Nginx의 설정 값 문제가 아니다. 하지만, Nginx를 제대로 알고 이해하고 있다면 원인을 파악하는 것도 장애에 대처하는 능력도 좋아질 것이다. 다음번엔 Nginx의 설정 값에 대해 포스팅해보도록 하겠다.

    댓글

Designed by Tistory.