Nginx 性能调优:HTTP 处理和配置
12 分钟阅读 - 2026年5月26日

调整 Nginx 工作进程、缓冲区、keepalive 和负载平衡,以便在单个服务器上每秒处理 50,000 多个请求。
Nginx HTTP 处理流程:配置调优
Nginx 的默认配置侧重兼容性而非性能。通过适当调优,单台服务器每秒可处理 50,000 至 80,000 次请求。本指南涵盖了最重要的设置:工作进程、连接、保持活动、缓冲、负载均衡,以及如何通过基准测试验证您的更改。
Nginx 如何处理 HTTP 请求
Nginx 通过不同的阶段处理请求,每个阶段都会消耗系统资源。了解这一流程有助于您针对性地调整设置。
该流程始于内核层。传入的连接进入 SYN 和 ACCEPT 队列,由 Nginx 工作进程进行处理。一旦接受连接,工作进程便会从内核缓冲区解析 HTTP 请求。对于 TLS 流量,此步骤将消耗更多 CPU 资源。
接下来,Nginx 会根据 Host 头部以及 IP/端口组合将请求匹配到虚拟服务器,然后通过前缀或正则表达式匹配将 URI 解析为 location 块。
对于动态内容,Nginx 将请求转发至后端(FastCGI、代理)。这一上游通信阶段极大受益于持久连接。若无上游 keepalive 机制,Nginx 将为每个请求建立新的 TCP 连接,从而增加延迟和 CPU 开销。
如果 proxy_buffering 启用该功能,Nginx 会在将响应交付给客户端之前,将完整的上游响应读入内存。这使得工作进程能够立即处理新的请求。最后,在输出交付过程中,启用 sendfile 可实现零拷贝传输,从而将吞吐量从约 6 Gbps 提升至 30 Gbps。
每个阶段都会消耗内存缓冲区、文件描述符和 CPU 周期。以下各节将针对每个瓶颈进行优化。
工作进程与连接
请从 worker_processes auto; 。这将使工作进程数与您的 CPU 核心数匹配。在核心数有限的 VPS 上,请手动设置该数值(例如 worker_processes 2;)。若工作负载对内存需求较高,请考虑减少工作进程数量,以避免内存超额分配。
启用 worker_cpu_affinity auto; 以将每个 worker 绑定到特定核心。这可减少缓存未命中和上下文切换。自 Nginx 1.9.10 起可用。
连接限制
worker_connections 指令用于设置每个 worker 可处理的并发连接数。总容量为 worker_processes × worker_connections。默认值 512 或 1,024 对于生产环境而言过低。对于高流量网站,应将每个 worker 的值设置为 2,048 或 4,096。
每个连接至少需要一个文件描述符。在反向代理配置中,每个连接会占用两个(一个用于客户端,一个用于上游)。将 worker_rlimit_nofile 的值至少为 worker_connections 值,并预留余量。对于 worker_connections 4096;,请使用 worker_rlimit_nofile 10000; 或更高版本。
在系统层面,将 fs.file-max 的值 /etc/sysctl.conf 至至少 500,000,并将 systemd 的 LimitNOFILE=65535.
最后,在 multi_accept on; ,以便 worker 进程能一次性接受所有待处理连接,而非逐个处理。
超时与保持活动
客户端保持活动
keepalive_timeout 指令控制闲置客户端连接保持打开的时间。对于高流量服务器,30 到 65 秒的效果很好。请使用双参数形式:
keepalive_timeout 65s 60s;第一个值是服务器端的超时时间。第二个值用于向客户端发送 Keep-Alive: timeout=60 标头。将客户端超时值设置得略低,可避免浏览器试图复用 Nginx 已关闭的连接所导致的竞争条件。
该 keepalive_requests 指令限制单个连接在关闭前处理的请求数量。默认值为 1,000(在 1.19.10 版本中从 100 提高)。对于稳定的后端,可将此值提高到 10,000 以减少连接波动。
代理超时
proxy_connect_timeout 用于设置 Nginx 等待与后端建立连接的时间。默认值为 60 秒。若需快速故障转移,请将其缩短至 5 至 10 秒。
proxy_read_timeout 定义 Nginx 在连续从上游读取数据之间等待的时间。请将其与后端的执行超时时间保持一致。如果 PHP-FPM 的 request_terminate_timeout 为 120 秒,请将 proxy_read_timeout 该值至少设为120秒,以避免过早触发504错误。
proxy_send_timeout 控制向上游连续写入之间的间隔。默认值 60 秒通常足够,除非您发送的是大型请求主体。
通常, proxy_connect_timeout 应始终是这三者中最短的。
缓冲区大小
client_body_buffer_size 控制 Nginx 在内存中保留多少传入请求正文的数据。默认值 8k 或 16k 可处理简单的表单提交,但文件上传会溢出到磁盘。对于中小型上传,请将其增加到 128k。如果用户上传较大文件,请将 client_max_body_size 若用户上传大文件,请将该值从默认的 1M 调高。
proxy_buffer_size 该参数将响应头与响应主体分开处理。默认值 4k 或 8k 通常适用,但使用大型 Set-Cookie (常见于电子商务)可能会超出此限制,导致 502 错误。请测量实际的头部大小:
curl -s -w '%{size_header}' -o /dev/null http://your-upstream-url将其向上取整至最接近的 4k 增量。
proxy_buffers 用于设置响应正文缓冲区的数量和大小。默认值(8 个 4k 或 8k 的缓冲区,总计 32k 至 64k)无法容纳大型 JSON 响应。请测量您最大的典型响应大小, curl ,并配置足够的缓冲区以将其完全保存在内存中。
代理缓冲行为
当 proxy_buffering on (默认值),Nginx 会在将响应发送给客户端之前,将完整的上游响应读入内存。这使得后端服务器能够立即处理新的请求。
将 proxy_busy_buffers_size 为至少 proxy_buffer_size 加上一个缓冲区,但小于您的总缓冲区池。对于 proxy_buffers 8 16k (总计 128k),请将 proxy_busy_buffers_size 小于 112k。
对于服务器发送事件(SSE)或长轮询等实时端点,请通过 proxy_buffering off 在特定位置的代码块中禁用缓冲。请有选择地将此设置应用于 /stream 或 /events 路径上,而非全局应用。
负载均衡与上游保持活动
默认情况下,Nginx 会为每个代理请求建立新的 TCP 连接。每次握手都会增加 10 到 100 毫秒的延迟,而 TLS 还会额外增加 10 到 50 毫秒。上游保持活动功能通过维护一组持久连接来消除这种开销。
需要配置以下三项设置:
upstream backend {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
keepalive 128;
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
} keepalive 参数用于设定每个 worker 的最大空闲连接数。计算最佳连接池大小公式如下: (workers × target concurrency) / upstream nodes.
将上游 keepalive_timeout 设置为 60 到 120 秒,以匹配后端设置并应对流量峰值。
负载均衡策略
Nginx 支持多种负载均衡方法。轮询(默认)按顺序分配请求。 least_conn 将请求路由至活动连接最少的服务器,这适用于请求持续时间不固定的负载。 ip_hash 通过将同一客户端 IP 路由到同一后端,提供会话保持功能。
当服务器容量不同时,请使用 weight 参数:
upstream backend {
least_conn;
server 10.0.1.10:8080 weight=3;
server 10.0.1.11:8080;
server 10.0.1.12:8080 backup;
keepalive 128;
}加权服务器接收三倍的流量。 backup 仅当所有主服务器均不可用时,该服务器才会激活。配置 max_fails 和 fail_timeout 用于被动健康检查,并使用 max_conns 来限制每个后端的服务器的并发连接数。
测试与监控
在进行任何更改之前,务必先测量基准性能。每次更改后,请重新进行基准测试。每次仅进行一项更改。
在重新加载前,请使用 nginx -t 进行验证。请在独立机器上运行基准测试,以避免资源竞争。
wrk 是 HTTP 负载测试的标准工具:
wrk -t4 -c200 -d30s http://your-server.com/跟踪每秒请求数、平均延迟、最大延迟和传输速率。Apache Bench 适用于更简单的测试:
ab -n 50000 -c 40 http://your-server.com/持续监控
启用 stub_status 模块,通过 curl http://localhost/nginx_status.
在日志格式中添加计时变量,以识别延迟发生的位置:
$request_time用于记录总请求时长$upstream_connect_time用于后端连接时间$upstream_response_time用于后端总处理时间
检查错误日志以排查缓冲区问题 journalctl -u nginx --no-pager | grep "temporary file"。如果响应涉及磁盘读写,说明您的 proxy_buffers 缓冲区过小。查找“打开的文件过多”错误,这表明 worker_rlimit_nofile 需要增加。
通过缓冲日志记录减少日志 I/O:
access_log /var/log/nginx/access.log combined buffer=64k flush=5s;在 ss -tn state established dst [backend_ip] 在负载测试中验证连接是否被复用,且未在 TIME_WAIT 状态中堆积。
关于针对高性能工作负载进行优化的专用服务器和VPS托管,请参阅FDC服务器。
如何优化 Linux 上的存储空间
15 分钟阅读 - 2026年5月22日