programing

큰 요청에 대해 응답 헤더를 업스트림에서 읽는 동안 Nginx 업스트림이 너무 일찍 닫혔습니다.

powerit 2023. 9. 15. 21:26
반응형

큰 요청에 대해 응답 헤더를 업스트림에서 읽는 동안 Nginx 업스트림이 너무 일찍 닫혔습니다.

저는 nginx와 노드 서버를 사용하여 업데이트 요청을 처리하고 있습니다.대용량 데이터에 대한 업데이트를 요청하면 게이트웨이 타임아웃이 발생합니다.nginx 오류 로그에서 이 오류를 확인했습니다.

2016/04/07 00:46:04 [오류] 28599#0: *1 업스트림에서 응답 헤더를 읽는 동안 업스트림 조기 닫힘 연결, 클라이언트: 10.0.2.77, 서버: gis.oneconcern.com , 요청: "GET /update_mbtiles/http 19891018000415 HTTP/1.1", 업스트림:"http://127.0.0.1:http7/update_mbtiles/http:19891018000415", 호스트: "gis.oneconcern.com "

구글에서 오류를 검색하고 할 수 있는 모든 것을 시도했지만 여전히 오류가 발생합니다.

내 nginx conf에는 다음과 같은 프록시 설정이 있습니다.

    ##
    # Proxy settings
    ##

    proxy_connect_timeout 1000;
    proxy_send_timeout 1000;
    proxy_read_timeout 1000;
    send_timeout 1000;

내 서버는 이렇게 구성됩니다.

server {
listen 80;

server_name gis.oneconcern.com;
access_log /home/ubuntu/Tilelive-Server/logs/nginx_access.log;
error_log /home/ubuntu/Tilelive-Server/logs/nginx_error.log;

large_client_header_buffers 8 32k;
location / {
    proxy_pass http://127.0.0.1:7777;
    proxy_redirect off;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $http_host;
    proxy_cache_bypass $http_upgrade;
}

location /faults {
    proxy_pass http://127.0.0.1:8888;
    proxy_http_version 1.1;
    proxy_buffers 8 64k;
    proxy_buffer_size 128k;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
}

}

저는 aws 서버에서 요청을 처리하기 위해 nodejs 백엔드를 사용하고 있습니다.업데이트에 오랜 시간(약 3-4분)이 걸릴 때만 게이트웨이 오류가 나타납니다.더 작은 업데이트에 대해서는 오류가 발생하지 않습니다.어떤 도움이라도 주시면 대단히 감사하겠습니다.

노드 js 코드:

app.get("/update_mbtiles/:earthquake", function(req, res){
var earthquake = req.params.earthquake
var command = spawn(__dirname + '/update_mbtiles.sh', [ earthquake, pg_details ]);
//var output  = [];

command.stdout.on('data', function(chunk) {
//    logger.info(chunk.toString());
//     output.push(chunk.toString());
});

command.stderr.on('data', function(chunk) {
  //  logger.error(chunk.toString());
 //   output.push(chunk.toString());
});

command.on('close', function(code) {
    if (code === 0) {
        logger.info("updating mbtiles successful for " + earthquake);
        tilelive_reload_and_switch_source(earthquake);
        res.send("Completed updating!");
    }
    else {
        logger.error("Error occured while updating " + earthquake);
        res.status(500);
        res.send("Error occured while updating " + earthquake);
    }
});
});

function tilelive_reload_and_switch_source(earthquake_unique_id) {
tilelive.load('mbtiles:///'+__dirname+'/mbtiles/tipp_out_'+ earthquake_unique_id + '.mbtiles', function(err, source) {
    if (err) {
        logger.error(err.message);
        throw err;
    }
    sources.set(earthquake_unique_id, source); 
    logger.info('Updated source! New tiles!');
});
}

감사해요.

프록시의 타임아웃 값을 높게 설정하여 이 문제를 해결했습니다.

location / {
    proxy_read_timeout 300s;
    proxy_connect_timeout 75s;
    proxy_pass http://localhost:3000;
}

문서: https://nginx.org/en/docs/http/ngx_http_proxy_module.html

Nginx의 오류는 nodejs 서버(즉, "upstream")에 의해 연결이 닫혔음을 나타내는 것이라고 생각합니다.nodejs는 어떻게 구성됩니까?

나는 꽤 오랫동안 같은 오류를 겪었고, 여기서 그것이 나를 위해 고쳐준 것입니다.

저는 단지 서비스상 다음과 같은 것을 사용한다고 선언했습니다.

Description= Your node service description
After=network.target

[Service]
Type=forking
PIDFile=/tmp/node_pid_name.pid
Restart=on-failure
KillSignal=SIGQUIT
WorkingDirectory=/path/to/node/app/root/directory
ExecStart=/path/to/node /path/to/server.js

[Install]
WantedBy=multi-user.target

여기서 주의를 끌 만한 것은 "After=network.target"입니다.

저는 nginx 쪽의 수정사항을 찾느라 며칠을 보냈는데, 문제는 그것뿐이었습니다.

이것이 문제인지 확인하려면 다음 단계를 따릅니다.

  1. 보유하고 있는 노드 서비스 실행 중지
  2. CLI에서 Exec Start 명령을 직접 실행합니다.
  3. 버그를 재현해 봅니다.

만약 그것이 터지지 않는다면, 그것은 단지 당신의 서비스에 문제가 있다는 것을 의미합니다.적어도 이것이 제가 제 답을 찾은 방법입니다.

다른 분들도 행운을 빌어요!

우연히 발견했습니다.*145660 upstream prematurely closed connection while reading upstreamNginx가 프록시 역할을 했던 서버에서 2GB 파일을 다운로드하려고 할 때 Nginx 오류 로그 항목이 발생했습니다.메시지는 "upstream" 연결이 닫혔지만 실제로 proxy_max_temp_file_size 설정과 관련이 있음을 나타냅니다.

구문: proxy_max_file_size;
기본값: proxy_max_file_size 1024m;
http, : http,버,치

프록시 서버의 응답 버퍼링이 활성화되어 있고 전체 응답이 proxy_buffer_size 및 proxy_buffer 지시에 의해 설정된 버퍼에 맞지 않을 경우 응답의 일부를 임시 파일에 저장할 수 있습니다.이 지시어는 임시 파일의 최대 크기를 설정합니다.한 번에 임시 파일에 기록되는 데이터의 크기는 proxy_temp_file_write_size 지시어로 설정됩니다.

파일에 합니다.0은에한답다을시다을답e은0f한so시ose

이 제한은 캐시되거나 디스크에 저장될 응답에는 적용되지 않습니다.

증상:

  • 다운로드가 1GB정도로 강제적으로 정지되고 있었습니다.
  • Nginx는 업스트림 폐쇄 연결을 주장했지만 프록시 서버가 없는 상태에서 전체 콘텐츠를 반환하고 있습니다.

해결책:

  • proxy_max_temp_file_size에 프록시 를 지정합니다.4096m전체 콘텐츠를 전송하기 시작했습니다.

약 50만 행을 내 API에 게시하려고 할 때 AWS Elastic Beanstalk 인스턴스의 로그에서 이 오류를 발견했습니다.

나는 여기에 있는 모든 충고를 따랐지만 소용이 없었습니다.

결국 EC2 인스턴스의 크기를 1개의 코어와 1GB RAM에서 4개의 코어와 8GB RAM으로 늘리는 것이 효과적이었습니다.

이렇게 노드의 타임아웃을 늘릴 수 있습니다.

app.post('/slow/request', function(req, res) {
    req.connection.setTimeout(100000); //100 seconds
    ...
}

이건 당신의 경우가 아닌 것 같은데 도움이 되는 사람이 있으면 올리겠습니다.저도 같은 문제가 있었는데 문제는 노드가 전혀 응답하지 않는다는 것이었습니다. (실패해도 아무 것도 하지 않는다는 조건이 있었습니다.) - 시간 초과를 늘린다고 해결되지 않았다면 모든 시나리오에 응답이 있는지 확인하십시오.

저도 이 문제에 부딪혀서 이 게시물을 찾았습니다.궁극적으로 이 답변들 중 어떤 것도 내 문제를 해결하지 못했고, 대신 나는 그것을 제거하기 위해 다시 쓰기 규칙을 넣어야 했습니다.location /rt개발자들이 만든 백엔드는 추가 경로를 기대하지 않았습니다.

┌─(william@wkstn18)──(Thu, 05 Nov 20)─┐
└─(~)──(16:13)─>wscat -c ws://WebsocketServerHostname/rt
error: Unexpected server response: 502

wscat을 사용하여 반복적으로 테스트한 결과 502 응답이 나왔습니다.Nginx 오류 로그가 위와 동일한 업스트림 오류를 제공했지만 업스트림 문자열에 GET 요청이 localhost:12775/rt 액세스를 시도하고 localhost:12775가 아닌 localhost:12775:

 2020/11/05 22:13:32 [error] 10175#10175: *7 upstream prematurely closed
 connection while reading response header from upstream, client: WANIP,
 server: WebsocketServerHostname, request: "GET /rt/socket.io/?transport=websocket
 HTTP/1.1", upstream: "http://127.0.0.1:12775/rt/socket.io/?transport=websocket",
 host: "WebsocketServerHostname"

개발자들이 웹소켓을 코딩하지 않았기 때문에 (12775에 따라) /rt/socket.io 을 기대하지 않고 /socket.io/ 만 코딩했습니다 (참고: /socket.io/ 은 여기서 논의된 웹소켓 전송을 지정하는 방법인 것 같습니다).이 때문에 소켓 코드를 다시 쓰라고 요구하는 것보다 WebsocketServerHostname/rt를 WebsocketServerHostname:12775로 번역하기 위해 다시 쓰기 규칙을 넣었습니다.

upstream websocket-rt {
        ip_hash;

        server 127.0.0.1:12775;
}

server {
        listen 80;
        server_name     WebsocketServerHostname;

        location /rt {
                proxy_http_version 1.1;

                #rewrite /rt/ out of all requests and proxy_pass to 12775
                rewrite /rt/(.*) /$1  break;

                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;

                proxy_pass http://websocket-rt;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;
        }

}

이 오류는 코드가 루프에 들어가는 경우에도 발생할 수 있습니다.따라서 이를 야기하는 (간접적으로) 자기 참조 코드가 있는지 조사해 보십시오.

저도 같은 문제에 직면해 있는데, 여기에 자세히 나와 있는 솔루션 중에서 아무도 제게 도움이 되지 않았습니다.우선 오류 413 Entity가 너무 커서 다음과 같이 nginx.conf를 업데이트했습니다.

http {
        # Increase request size
        client_max_body_size 10m;

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;

        ##
        # Proxy settings
        ##
        proxy_connect_timeout 1000;
        proxy_send_timeout 1000;
        proxy_read_timeout 1000;
        send_timeout 1000;
}

그래서 http 부분만 업데이트했는데 지금 오류 502 Bad Gateway를 만나고 /var/log/nginx/error.log를 표시하면 "upstream에서 응답 헤더를 읽는 동안 upstream surly closed connection"이라는 유명한 메시지가 표시됩니다.

저에게 정말로 의문스러운 것은 서버에서 virtualenv로 실행하고 요청을 다음: IP:8000/nameOf로 전송하면 요청이 작동한다는 것입니다.더 리퀘스트

읽어주셔서 감사합니다.

같은 오류가 발생했습니다. 해결 방법은 다음과 같습니다.

  • AWS에서 로그를 다운로드했습니다.
  • Nginx 로그 검토, 위와 같은 추가 세부 사항 없음.
  • node.js 로그를 검토했습니다. AccessDenied AWS SDK 권한 오류입니다.
  • AWS에서 읽으려고 했던 S3 버킷을 확인했습니다.
  • 서버 역할을 수정하기 위해 읽기 권한이 있는 버킷을 추가했습니다.

대용량 파일을 처리하고 있었지만 S3 접근이 누락된 것을 수정하면 다른 오류나 설정을 변경해야 했습니다.

문제

업스트림 서버가 타임아웃 중인데 무슨 일이 일어나고 있는지 모르겠어요.

서버가 데이터베이스에 연결된 경우 읽기 또는 쓰기 제한 시간을 늘리기 전에 먼저 확인할 위치

서버가 데이터베이스에 연결 중인데, 이 연결은 정상적인 응답 시간 내에 정상적으로 작동하며, 서버 응답 시간 지연을 초래하는 것은 아닙니다.

연결 상태가 업스트림에서 계단식 장애를 일으키지 않는지 확인합니다.

그런 다음 이동하여 서버 및 프록시의 읽기 및 쓰기 시간 초과 구성을 확인할 수 있습니다.

언급URL : https://stackoverflow.com/questions/36488688/nginx-upstream-prematurely-closed-connection-while-reading-response-header-from

반응형