基于本文回答

播面 播面

刷题像听歌,多听自然懂
0
评论

Nginx 代理长连接(Keep-Alive)如何配置?它的主要作用和优化效果是什么?

在 Nginx 中,长连接(Keep-Alive)的配置非常重要,特别是在高并发场景下。由于 Nginx 通常作为反向代理,处于客户端和后端服务之间,因此长连接的配置分为两个方向

  1. 客户端 到 Nginx 的长连接。
  2. Nginx 到 后端服务(Upstream) 的长连接。

以下是详细的配置方法、主要作用以及优化效果。


一、 如何配置 Nginx 长连接?

1. 客户端 <---> Nginx 的长连接配置

这部分通常在 httpserverlocation 模块中配置。Nginx 默认是开启客户端长连接的,但可以根据实际业务调整参数。

plaintext
http {
    # 设置长连接的超时时间。超过这个时间没有发送新请求,Nginx 将关闭连接。
    # 默认是 75 秒。建议根据业务调整,通常设为 30-60 秒即可。
    keepalive_timeout  60s; 

    # 在一个长连接上最多允许处理的请求数量。
    # 超过这个数量后,Nginx 会强制关闭连接。默认是 1000(旧版本默认是 100)。
    # 对于页面包含大量静态资源(图片、CSS、JS)的情况,建议调大。
    keepalive_requests 2000; 

    # (可选) 告诉 Nginx 在空闲多久后发送 TCP keepalive 探测包(仅限于 Linux 系统)
    # tcp_nodelay on;
}

2. Nginx <---> 后端服务(Upstream)的长连接配置

(最容易被忽略且最关键的一步)
默认情况下,Nginx 代理到后端的请求使用的是 HTTP/1.0,并且在每次请求结束后会关闭连接(短连接)。要开启长连接,必须在 upstream 和代理的 location 中同时配置。

plaintext
http {
    upstream backend_servers {
        server 127.0.0.1:8080;
        server 127.0.0.1:8081;

        # 【核心配置】设置到 upstream 服务器的空闲长连接的最大数量。
        # 注意:这指的是“每个 worker 进程”保持的“空闲”连接数,而不是最大连接数。
        # 如果空闲连接超过这个数,最近最少使用的连接会被关闭。
        keepalive 100; 

        # (Nginx 1.15.3+) 代理长连接超时时间
        keepalive_timeout 60s;
        
        # (Nginx 1.15.3+) 一个代理长连接上最多处理的请求数
        keepalive_requests 1000;
    }

    server {
        listen 80;
        
        location /api/ {
            proxy_pass http://backend_servers;
            
            # 【核心配置】必须指定 HTTP 协议版本为 1.1(HTTP/1.0 不支持 Keep-Alive)
            proxy_http_version 1.1;
            
            # 【核心配置】必须清除 "Connection" 请求头。
            # 因为客户端发来的可能是 Connection: close,如果不清除直接透传,后端依然会断开连接。
            proxy_set_header Connection ""; 
            
            # 其他常规配置...
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

二、 长连接的主要作用

HTTP 协议是基于 TCP 的。在短连接模式下,每一次 HTTP 请求都需要经历:
TCP 三次握手 -> 传输 HTTP 数据 -> TCP 四次挥手

长连接(Keep-Alive)的主要作用就是复用 TCP 连接。在一个 TCP 连接建立后,不立即断开,而是保持一段时间,在这段时间内同一客户端发起的后续 HTTP 请求都会复用这个 TCP 连接。


三、 优化效果(为什么要配置?)

  1. 降低延迟,提升响应速度 (降低 RT/TTFB)

    • 省去了每次请求时的 TCP 三次握手和慢启动时间。尤其在高频 API 请求或网页加载大量静态资源时,响应速度会有肉眼可见的提升。如果开启了 HTTPS,更能省去昂贵的 TLS 握手时间。
  2. 大幅降低 CPU 和内存消耗

    • 不论是 Nginx 本身还是后端(如 Tomcat、Node.js、PHP-FPM),频繁地建立和销毁 TCP 连接都需要消耗大量的 CPU 资源和内存来维护连接状态(TCP Control Block)。长连接极大减轻了服务器的计算压力。
  3. 防止端口耗尽 (解决 TIME_WAIT 过多问题)

    • 在高并发的短连接场景下,Nginx 频繁关闭连接会导致系统中出现大量的 TIME_WAIT 状态的 TCP 连接。
    • 每个 TIME_WAIT 会占用系统临时端口长达 60 秒(Linux 默认)。如果并发极高,会导致 Nginx 代理机器的 65535 个端口被耗尽,从而抛出 Cannot assign requested address 的 502/504 错误。开启长连接是解决此问题的根本方法。
  4. 提升整体吞吐量 (QPS/TPS)

    • 由于 CPU 消耗减少、网络拥塞控制(TCP 慢启动)减少,服务器在同等硬件配置下能够承载更多的并发请求。

四、 配置注意事项与避坑指南

  1. upstream 中的 keepalive 参数不要设置得过大
    • 这里的数字是空闲连接池的大小,不是最大连接数。如果设置得太大(比如几万),会导致 Nginx 和后端保持大量无效的空闲连接,白白占用双方的内存和文件描述符。一般根据 QPS 情况,设置为 100 ~ 1000 即可满足绝大部分中大型业务需求。
  2. 前后端超时时间需匹配
    • Nginx 到后端的 keepalive_timeout(假设为 60s)应该小于 后端服务器(如 Tomcat、Spring Boot)自身的长连接超时时间(如 65s)。
    • 如果 Nginx 的超时时间长于后端,后端主动断开了连接,而 Nginx 还以为连接可用并把新请求发过去,就会导致 502 Bad Gateway 错误。
  3. L4 负载均衡的干扰
    • 如果 Nginx 后面还有一层负载均衡(如阿里云 SLB、AWS ALB),需要确保那一层的长连接配置与 Nginx 兼容。
00:00
00:00