首页 / 博客 / 本文

Nginx 高性能调优实战:从默认配置到生产级静态站

🚀 性能优化📅 2026-08-29⏱ 14 分钟

很多人部署 Nginx 时直接沿用发行版默认配置——能用,但远不是最优。本文以一台 Debian 12 + 静态站为例,从「进程模型 → 传输层 → 压缩 → 缓存 → 限流」五个层面,给出可直接落地的生产级调优清单。这套配置在本站(TechPulse)真实运行,效果可测。

先理解基线。Nginx 本身就是为高并发而生的。调优的目标不是「把它调得更猛」,而是让它在同等硬件下:少建连接、少回源、少解压、少查盘。一切参数都要服务于这四个「少」。

一、进程模型:让 worker 数与硬件匹配

1. worker_processes

默认值 1 只用一个进程,浪费多核 CPU。现代机器建议直接设 auto,Nginx 会按 CPU 核数自动分配。

worker_processes auto;
worker_cpu_affinity auto;   # 多核绑定,减少进程迁移开销

2. worker_connections 与事件模型

events {
    worker_connections 4096;   # 单 worker 最大并发连接(默认 768 偏小)
    use epoll;                 # Linux 下默认即 epoll,显式声明更清晰
    multi_accept on;           # 一次 accept 尽量多接
}

理论峰值并发 ≈ worker_processes × worker_connections。4 核机器配 4096,即可支撑约 1.6 万并发连接——对个人站来说绰绰有余。

二、传输层:sendfile 与 TCP 优化

sendfile on;          # 零拷贝发静态文件,绕开用户态内存拷贝
tcp_nopush on;        # 攒够一个包再发,配合 sendfile 减少小包
tcp_nodelay on;       # 小文件/API 响应立即发,不等待 Nagle
keepalive_timeout 30s;# HTTP 长连接保持时间(15~60s 均可)
keepalive_requests 1000; # 单连接最多复用请求数,默认 100 可调大

sendfile 对静态站收益最大——文件直接从磁盘到网卡,CPU 几乎不参与。注意:sendfile 与 gzip 同时开启时,压缩会在发送阶段进行,配合预压缩的 .gz 文件效果最佳(见下文)。

三、压缩:gzip + gzip_static,省一半流量

3. gzip 基础配置

gzip on;
gzip_comp_level 6;                        # 1~9,6 是性价比甜点
gzip_min_length 1024;                     # 小于 1KB 不压(压缩反而更大)
gzip_types text/plain text/css application/json
           application/javascript image/svg+xml
           application/xml application/xml+rss;
gzip_vary on;                             # 返回 Vary: Accept-Encoding,利于中间缓存

4. gzip_static:预压缩,彻底消除「解压再压缩」

运行时 gzip 每次请求都要现场压缩,很耗 CPU。若部署时已经生成 .gz 文件,开启 gzip_static on 后 Nginx 直接发预压缩文件,CPU 占用几乎归零。

# nginx.conf 中
gzip_static on;
# 生成预压缩文件(CSS/JS 等静态资源)
gzip -9 -k style.css main.js tools.js vendor/*.js

本站的 assets/js/vendor/*.js(如 pdf-lib、pptxgen)体积以 MB 计,预压缩后传输量直接降到 1/4~1/3,首屏收益立竿见影。

四、缓存:让「命中」代替「回源」

5. 静态资源长缓存 + 指纹刷新

location ^~ /assets/ {
    expires 7d;
    add_header Cache-Control "public, max-age=604800" always;
    try_files $uri =404;
}

注意配套策略:CSS/JS 文件名带 ?v=N 或内容哈希作为「指纹」,改版时更新指纹即可强制刷新,旧缓存自然失效。

6. HTML 页面:绝不长缓存

location ~* \.html$ {
    expires -1;
    add_header Cache-Control "no-cache, must-revalidate" always;
}

HTML 是「入口」,一旦被浏览器/代理长缓存,用户就永远看不到新版本。用 no-cache, must-revalidate:每次导航都回源校验(返回 304,极快),拿到新版本就立刻替换——这是静态站最常见的翻车点。

7. open_file_cache:把「打开文件」也缓存起来

open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;      # 访问 2 次以上才缓存句柄
open_file_cache_errors on;       # 把「文件不存在」也缓存,防 404 风暴

静态站高频访问同一批文件,缓存文件句柄、元数据后,连 stat() 系统调用都省了,QPS 能再上一个台阶。

五、限流与安全:好性能的前提是「不被拖垮」

8. 全局限速 + 接口独立限速

limit_req_zone $binary_remote_addr zone=general:10m rate=30r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;

server {
    limit_req zone=general burst=300 nodelay;   # 全局:突发 300
    location = /api/ {
        limit_req zone=api burst=20 nodelay;     # 接口:更严
    }
}

限速不是降低性能,而是「削峰」。没有限流,一次 CC/爬虫风暴就能让之前所有优化归零。

9. 敏感路径与隐藏版本

server_tokens off;                          # 隐藏版本号
location ~ /\.(?!well-known) { deny all; }  # 隐藏点开头文件
location ~* \.(env|log|bak|sql|sh|py)$ { deny all; }

六、实测:调优前后对比

指标默认配置调优后
静态 CSS(gzip 后)传输量5.1KB1.9KB(gzip_static)
pdf-lib.min.js 传输量516KB206KB
首屏 HTML 校验完整 200 响应304 命中(<1ms)
单 worker 并发7684096
总结。静态站性能优化的优先级:① 压缩(gzip_static)② 静态资源长缓存 + HTML 短缓存 ③ sendfile/open_file_cache ④ worker 数与连接数匹配 ⑤ 限流兜底。按这个顺序做,收益递减但每个都值得。先量(curl -w、Lighthouse、浏览器 Network),再调,不要凭感觉乱加参数。
#Nginx#性能优化#运维#静态站
广告