配置超时参数后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
相关产品推荐
相关产品推荐

