在 Nginx 的 upstream 配置块中启用 keepalive 参数,能让 Nginx 与后端服务维持持久连接,适用于减少频繁 TCP 握手带来的负载压力。
先说结论:配置 upstream 长连接能有效降低 Nginx 与后端之间的握手开销,但需要后端服务支持 HTTP/1.1 持久连接。
- 适合:后端支持 HTTP/1.1 持久连接的反向代理场景
- 先做:在 upstream 块中设置 keepalive 连接数并调整 proxy 协议版本
- 再验证:通过系统命令观察后端端口连接状态是否稳定
命令速用版
upstream backend_pool {
server 127.0.0.1:8080;
keepalive 32;
}
server {
location / {
proxy_pass http://backend_pool;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}为什么会这样
Nginx 作为反向代理时,它既是客户端的服务端,也是后端服务的客户端。默认情况下,如果未配置长连接,Nginx 处理每个请求都可能与后端建立一次新的 TCP 连接,这需要经过三次握手和慢启动过程。开启 keepalive 后,Nginx 会在完成请求后不立即关闭与后端的连接,而是放入连接池供后续请求复用,从而减少 CPU 消耗和网络延迟。
分步处理
- 编辑配置文件:找到定义后端的 upstream 块,添加
keepalive指令,数值根据后端承受能力设定,例如 32 或 64。 - 调整代理协议:在引用该 upstream 的
location块中,设置proxy_http_version 1.1;。HTTP/1.0 默认请求结束后关闭连接,必须切换到 1.1 才能支持持久连接。 - 清除连接头:添加
proxy_set_header Connection "";。这能防止 Nginx 将客户端的Connection: close头传递给后端,避免后端主动关闭连接。 - 检查并重载:执行
nginx -t检查语法,确认无误后执行nginx -s reload生效。
怎么验证是否生效
配置生效后,Nginx 日志默认不会直接显示连接复用情况,可以通过观察系统网络连接状态来推断:
- 观察连接数:在高并发请求期间,使用
ss -ant | grep <后端端口> | wc -l统计与后端的连接数。如果配置生效,连接数应维持在keepalive设定值附近,而不是随请求量线性增长。 - 查看状态:使用
ss -ant | grep <后端端口>查看连接状态,应看到较多ESTABLISHED状态的连接保持稳定,而不是频繁出现TIME_WAIT堆积。 - 后端日志:如果有权限查看后端服务日志,观察新建连接日志的频率是否下降。
常见坑
- 混淆配置块:
keepalive在http块中是控制客户端到 Nginx 的连接,在upstream块中才是控制 Nginx 到后端的连接,两者互不影响。 - 后端不支持:如果后端服务(如某些旧版应用服务器)不支持 HTTP/1.1 或不允许长连接,Nginx 侧配置再生效也无法复用,甚至可能导致请求挂起。
- 连接数过大:
keepalive设置的数值不是越大越好,每个空闲连接都会占用后端服务的文件描述符和内存,需根据后端最大连接数限制合理设定。 - 未清除 Header:忘记设置
proxy_set_header Connection "";是常见失误,这会导致后端收到关闭指令,长连接无法建立。
参考来源
- Nginx 官方文档 - ngx_http_upstream_module 模块说明,指令 keepalive,URL: https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive
- Nginx 官方文档 - ngx_http_proxy_module 模块说明,指令 proxy_http_version,URL: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version