You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

配置超时参数后NGINX proxy-pass仍60秒截断连接

NGINX代理超时问题:60秒后连接被截断,已配置超时参数仍无效

我有一台执行耗时超60秒操作的服务器,直接连接时一切正常,但通过NGINX 1.22.1版本代理后,60秒连接就会被截断,服务器响应无法送达客户端。

复现脚本

用以下Python脚本可复现该场景:

import time
from http.server import BaseHTTPRequestHandler, HTTPServer

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/plain')
        self.end_headers()
        time.sleep(66)
        self.wfile.write(b'Hello, world!')

if __name__ == '__main__':
    server_address = ('', 3000)
    httpd = HTTPServer(server_address, MyHandler)
    print('Server listening on port 3000...')
    httpd.serve_forever()

已尝试的NGINX配置(未生效)

server {
    listen 80;
    server_name xxx.my.domain;

    location / {
        proxy_pass http://192.168.4.150:3000;
        proxy_connect_timeout 120s;
        proxy_send_timeout 120s;
        proxy_read_timeout 120s;
        send_timeout 120s;
    }
}

问题现象

  • Postman提示:Could not get response - Error: socket hang up
  • curl返回:
* Empty reply from server
* Closing connection 0
curl: (52) Empty reply from server
  • Chrome提示:ERR_EMPTY_RESPONSE

当Python脚本中等待时间缩短至50秒时,请求可正常完成,已尝试禁用缓存、保持连接等设置,均无效果。


解决建议

1. 补充全局及location级别的完整超时配置

部分全局超时参数可能覆盖location设置,需在http块和location块中同时配置完整超时项,并启用HTTP/1.1连接保持:

http {
    # 全局超时配置
    client_body_timeout 120s;
    client_header_timeout 120s;
    keepalive_timeout 120s;

    server {
        listen 80;
        server_name xxx.my.domain;

        location / {
            proxy_pass http://192.168.4.150:3000;
            proxy_connect_timeout 120s;
            proxy_send_timeout 120s;
            proxy_read_timeout 120s;
            send_timeout 120s;
            # 启用HTTP/1.1并清除Connection头,避免长连接被强制断开
            proxy_http_version 1.1;
            proxy_set_header Connection "";
        }
    }
}

2. 启用NGINX调试日志定位根因

通过调试日志可明确连接断开的触发方(NGINX/后端/中间设备),在http块中添加:

http {
    error_log /var/log/nginx/error.log debug;
    # 其他配置...
}

重启NGINX后触发请求,查看error.log中60秒左右的日志条目,确认断开具体原因。

3. 检查操作系统TCP层面的超时设置

Linux系统的TCP keepalive参数若被修改为较短值,可能导致系统主动关闭连接,执行以下命令检查:

sysctl net.ipv4.tcp_keepalive_time
sysctl net.ipv4.tcp_keepalive_intvl
sysctl net.ipv4.tcp_keepalive_probes

若参数值过小,可临时调整:

sysctl -w net.ipv4.tcp_keepalive_time=300
sysctl -w net.ipv4.tcp_keepalive_intvl=60
sysctl -w net.ipv4.tcp_keepalive_probes=5

如需永久生效,将上述参数写入/etc/sysctl.conf后执行sysctl -p。

4. 后端启用分块传输保持连接活跃

NGINX的proxy_read_timeout检测的是“连续无数据传输”的超时,若后端长时间不发送数据,即使配置了超时参数仍可能触发断开。修改Python脚本启用分块传输:

import time
from http.server import BaseHTTPRequestHandler, HTTPServer

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/plain')
        self.send_header('Transfer-Encoding', 'chunked')
        self.end_headers()
        
        # 发送空分块保持连接活跃
        self.wfile.write(b'0\r\n\r\n')
        self.wfile.flush()
        
        time.sleep(66)
        
        # 发送实际内容(遵循分块格式:长度16进制+CRLF+内容+CRLF)
        self.wfile.write(b'c\r\nHello, world!\r\n')
        # 结束分块传输
        self.wfile.write(b'0\r\n\r\n')
        self.wfile.flush()

if __name__ == '__main__':
    server_address = ('', 3000)
    httpd = HTTPServer(server_address, MyHandler)
    print('Server listening on port 3000...')
    httpd.serve_forever()

5. 排查中间网络设备

若上述配置均无效,需检查NGINX与后端服务器之间是否存在防火墙、负载均衡等设备,这些设备可能自带60秒超时规则,需要调整其连接超时设置。


内容的提问来源于stack exchange,提问作者talpaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 03:25:18