配置Nginx 的 Keepalive 提升每秒查询率(QPS)

Nginx 的 Keepalive 功能通过复用已经建立的 TCP 连接来处理多个 HTTP 请求,避免了为每个请求都重新建立连接的巨大开销,从而显著提升了每秒查询率(QPS)。

其性能提升主要源于避免了以下两个耗时的过程:

  1. 避免 TCP 三次握手

    • 没有 Keepalive:每个 HTTP 请求都需要经历一次完整的 TCP 三次握手(SYN, SYN-ACK, ACK),这会引入至少一个网络往返时间(RTT)的延迟。
    • 启用 Keepalive:在第一个请求完成后,TCP 连接会保持打开状态。后续的请求可以直接复用这个"空闲"的连接,省去了重复的握手过程。
  2. 避免 TLS 握手(针对 HTTPS)

    • 如果服务是 HTTPS,每次新建 TCP 连接后还需要进行一次昂贵的 TLS 握手,这个过程涉及复杂的加密计算,会消耗大量的 CPU 资源。
    • 启用 Keepalive 后,TLS 会话也可以被复用,极大地降低了 CPU 负载和请求延迟。

简单来说,Keepalive 将"建立连接 → 发送请求 → 关闭连接 "的模式,变成了"建立连接 → 发送多个请求 → 关闭连接",大大减少了系统资源的消耗和请求的等待时间。

🔧 Nginx Keepalive 详解与配置

Nginx 的 Keepalive 配置分为两部分:客户端到 NginxNginx 到后端服务器(Upstream)

1. 客户端 ↔ Nginx 的长连接

这部分控制 Nginx 如何处理来自浏览器等客户端的连接。

  • keepalive_timeout : 定义 Nginx 与客户端的空闲连接保持打开的时长。
    • 示例 : keepalive_timeout 65; (保持65秒)
  • keepalive_requests : 定义在一个长连接上最多可以处理多少个请求,超过后连接会被关闭。这可以防止单个连接占用资源过久。
    • 示例 : keepalive_requests 1000;

配置位置 : 通常放在 http 块中。

复制代码
http {
   # ... 其他配置 ...
    keepalive_timeout 65;
    keepalive_requests 1000;
}
2. Nginx ↔ 后端服务器 (Upstream) 的长连接

这部分是提升 QPS 的关键,它控制 Nginx 作为反向代理时,如何与后端的 Java、Python、Go 等应用服务器复用连接。

  • keepalive : 在 upstream 块中定义,表示 Nginx 为每个工作进程保留的、与后端服务器的空闲连接池大小。
    • 示例 : keepalive 32; (建议从 16-64 开始调优)
  • proxy_http_version : 在 location 块中,必须设置为 1.1,因为 HTTP/1.1 默认支持长连接。
    • 示例 : proxy_http_version 1.1;
  • proxy_set_header Connection "" : 这是最关键的一步!它的作用是清空请求头中的 Connection 字段。如果不设置,Nginx 可能会将客户端的 Connection: close 头传递给后端,导致后端在处理完一个请求后就关闭连接,使得 keepalive 配置失效。

配置位置 : upstream 块和 location 块协同配置。

复制代码
# 定义后端服务器组
upstream my_backend {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
    keepalive 32; # 启用长连接池,大小为32
}

server {
    listen 80;

    location / {
        proxy_pass http://my_backend;
        
        # 启用 upstream keepalive 的关键配置
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        
        # 其他代理配置...
        proxy_set_header Host $host;
    }
}

TCP 连接的唯一性

一个 TCP 连接是由一个唯一的"四元组"来标识的:

  • 源 IP 地址 (Source IP)
  • 源端口号 (Source Port)
  • 目标 IP 地址 (Destination IP)
  • 目标端口号 (Destination Port)

只要这四个值中任何一个不同,就代表一个全新的、独立的 TCP 连接。

当两个不同的客户端(例如,两个不同的浏览器,或者两台不同的电脑)访问同一个 Nginx 服务器时,它们的源 IP 地址必然是不同的。因此,它们与 Nginx 建立的 TCP 连接从一开始就是两个完全独立的连接,物理上就不可能复用。

一个形象的比喻

您可以将 Nginx 服务器想象成一个餐厅,而 TCP 连接就是餐桌。

  • Keepalive (长连接) :指的是同一位客人(同一个客户端) 在吃完一道菜(完成一个HTTP请求)后,不必离开餐厅,可以坐在**同一张餐桌(同一个TCP连接)**上继续点下一道菜。这节省了重新找位、带位的时间。
  • 不同客户端 :指的是两位不同的客人(两个不同的客户端)。他们不可能也不应该坐在同一张餐桌上吃饭。餐厅(Nginx)会为每一位新来的客人提供一张新的、独立的餐桌(建立一个新的TCP连接)。

所以,Keepalive 优化的是"一位客人"的用餐体验,而不是让"所有客人"挤在一张桌子上。

Nginx 的实际工作机制

Nginx 作为高性能服务器,其核心能力之一就是高并发处理。它会为每一个 incoming 的客户端连接创建一个独立的上下文来处理请求。

  1. 客户端 A 向 Nginx 发起请求,Nginx 接受后,会建立一个 TCP 连接(我们称之为 连接A)。
  2. 客户端 B 也向 Nginx 发起请求,Nginx 会接受并建立另一个全新的 TCP 连接(我们称之为 连接B)。
  3. 如果客户端 A 启用了 Keepalive,那么它在短时间内发起的第二个、第三个请求,会继续使用 连接A
  4. 同样,客户端 B 的后续请求也会复用 连接B

连接A连接B 在 Nginx 内部是完全隔离的,它们的数据流、状态和生命周期都互不干扰。

Nginx 反向代理Upstream Keepalive

  • 客户端 → Nginx :这个阶段,连接是一对一的,不同客户端的连接绝对不能复用。
  • Nginx → 后端服务器 (Upstream) :这个阶段,Nginx 会维护一个连接池 。为了高效地与后端应用服务器(如 Tomcat, Gunicorn)通信,Nginx 会预先建立一批长连接放在池子里。
    • 来自客户端A 的请求,经过 Nginx 处理后,可能会通过连接池中的 连接1 转发给后端。
    • 紧接着,来自客户端B 的请求,也可能会通过连接池中的 连接1 转发给后端。

在这种情况下,是 Nginx 在复用它与后端服务器之间的连接 ,来服务不同的客户端。但请注意,对于客户端来说,它们各自与 Nginx 的连接依然是独立的。这个复用过程对客户端是完全透明的。

特性 Nginx Keepalive (长连接)
作用层面 网络层 (TCP 连接)
核心目的 复用 TCP 连接,减少网络握手开销
解决的问题 提升 QPS,降低网络延迟
必要性 必要。优化所有 HTTP 请求的基础设施。
相关推荐
欧阳天风6 分钟前
electron播放本地音乐的问题
前端·javascript·electron
艾伦野鸽ggg9 分钟前
CSS布局与动效知识梳理
前端·css
ljt272496066113 分钟前
Vue笔记(二)--组件的属性和方法
前端·vue.js·笔记
Boop_wu14 分钟前
[前端] CSS 常用样式(聊天界面 / 网页布局专用)
前端·css·css3
JiaWen技术圈14 分钟前
Web 安全防护 介绍
运维·nginx·安全
声声codeGrandMaster15 分钟前
React框架的基础代码使用
前端·react.js·前端框架
叫我少年19 分钟前
Vue 3 集成 Vue Router:从基础配置到项目实践
前端·路由
Highcharts.js19 分钟前
Highcharts React 5.0 正式版:支持 ES 模块化、组件更精简、开发体验全面升级
前端·javascript·react.js·elasticsearch·前端框架·highcharts
大江东去浪淘尽千古风流人物24 分钟前
【X-Restormer++】全天候图像恢复赛冠军方案:三项创新解析及对VIO/SLAM前端的工程价值
前端
LaughingZhu26 分钟前
Claude Code 时代的写作:为什么 HTML 正在取代 Markdown
前端·人工智能·html