要在 Nginx 反向代理中启用 keepalive 长连接,核心是在 upstream 块中设置 keepalive 参数,并在 location 块中强制使用 HTTP/1.1 协议且清除 Connection 头。这适用于 Nginx 与后端服务之间频繁通信的场景,能有效减少 TCP 握手开销。
先说结论:配置正确后,Nginx 与后端服务之间会复用 TCP 连接,避免频繁握手,但需确保后端服务本身支持并保持长连接。
- 适合后端响应快且并发较高的场景
- 先调整 upstream 和 location 配置项
- 再观察后端连接数及日志变化
核心配置步骤
配置涉及两处关键修改:upstream 块定义连接池,location 块指定协议版本和头信息。请确保 Nginx 版本支持 upstream keepalive(大多数现代版本均支持)。
http {
upstream backend {
server 192.168.1.10:8080;
keepalive 32; # 设置空闲长连接数量,非最大并发数
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1; # 强制使用 HTTP/1.1
proxy_set_header Connection ""; # 清除 Connection 头,避免关闭
}
}
}注意:keepalive 数值表示每个 worker 进程维护的空闲连接数。设置过大可能占用过多文件描述符,设置过小则复用效果不明显。通常根据 worker 数量和后端承载能力调整,一般设置为后端实例数的 2-4 倍。
验证长连接是否生效
配置完成后,需通过可靠手段验证 Nginx 与后端之间是否复用了连接。
1. 避免使用 curl -v 直接验证 upstream 头
curl -v 只能查看客户端到 Nginx 的交互头信息,无法直接看到 Nginx 到后端的请求头。因此,不能仅凭 curl 输出判断 upstream keepalive 是否生效。
2. 使用 tcpdump 抓包分析(推荐)
在 Nginx 服务器上抓包,观察 Nginx 与后端 IP 之间的流量。如果配置生效,多次请求中应看到 Connection: keep-alive 且 TCP 连接未频繁断开重建。
sudo tcpdump -i any -A 'port 8080 and host 192.168.1.10' | grep -i connection观察输出中是否持续出现 Connection: keep-alive,且同一 TCP 会话中承载了多个 HTTP 请求。
3. 查看后端应用日志
如果后端服务(如 Tomcat、Go、Node.js)记录了请求头,检查日志中接收到的 Connection 字段。若配置生效,该字段应为空或 keep-alive,而非 close。
4. 观察后端连接数
在后端服务器上查看当前建立的 TCP 连接数。如果配置生效,在高并发请求下,活跃连接数应趋于稳定,而不是随请求量线性增长。
ss -ant | grep :8080 | wc -l常见坑与排查
- 默认协议版本:如果不显式设置
proxy_http_version 1.1,Nginx 默认可能使用 1.0,导致 keepalive 不生效。建议显式声明。 - 后端主动关闭:即使 Nginx 配置了长连接,如果后端服务配置了较短的 keepalive 超时时间,或者主动返回
Connection: close,连接仍会被断开。需确保后端也允许长连接。 - 文件描述符限制:keepalive 连接会占用文件描述符。如果系统 ulimit 设置过小,可能导致 Nginx 无法建立足够的长连接,需检查
worker_connections及系统限制。 - 鉴权或特殊 header:某些场景下,如果请求中包含特定 header 导致后端认为必须新建连接,长连接也会失效。需结合后端日志排查。
参考来源
- Nginx 官方文档 - ngx_http_upstream_module: http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive
- Nginx 官方文档 - ngx_http_proxy_module: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version