一个网页通常由HTML + CSS + JS 组成,这些全是文本文件,压缩率极高。不压缩时,一个 200KB 的 JS 文件走网络就是 200KB;开了Gzip,可能只剩 50KB。
| 项目 | 不开 Gzip | 开 Gzip |
|---|---|---|
| HTML 文件 100KB | 传输 100KB | 传输约 20KB |
| CSS 文件 80KB | 传输 80KB | 传输约 16KB |
| JS 文件 200KB | 传输 200KB | 传输约 50KB |
| 图片 / 视频 | 已经是压缩格式 | 不压缩 |
| 带宽消耗 | 100% | 约 25%-35% |
| 首次加载速度 | 基准 | 快 40%-60% |
💡 提示: Gzip 只对文本文件有效。图片(JPEG/PNG/WebP)、视频(MP4)、已经压缩的文件(ZIP/GZ)不要再压缩,既没有效果还白费 CPU。
以下配置直接放在nginx.conf 的 http 块里即可。
# /etc/nginx/nginx.conf 的http 块里
http {
# 开启 Gzip
gzip on;
# 压缩级别 1-9
# 1 最快压缩率最低,9 最慢压缩率最高
# 推荐 4-6,性价比最高
gzip_comp_level 5;
# 最小压缩文件大小(小于此值不压缩)
# 太小的文件压缩后可能更大,还浪费 CPU
gzip_min_length 1k;
# 压缩的文件类型
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/xml+rss
| 级别 | CPU 占用 | 压缩率 | 推荐场景 |
|---|---|---|---|
| 1 | 最低 | 约 70% | CPU 紧张的高并发服务器 |
| 4 | 较低 | 约 75% | 一般生产环境 |
| 6 | 中等 | 约 80% | 推荐默认值 |
| 9 | 最高 | 约 82% | 几乎没意义, CPU 换来 2% 提升 |
⚠️ 注意: 级别 6 和 9 的压缩率差异不到 3%,但 CPU占用差一倍。绝大多数场景选 5 或 6 就行,别纠结。
如果看不到Content-Encoding: gzip,检查:
| 排查项 | 检查方法 |
|---|---|
| gzip on 没写 | 看 nginx.conf 的 http 块 |
| 文件类型没包含 | 确认 gzip_types 里有对应类型 |
| 文件太小 | 确认文件大于 gzip_min_length |
| 请求头没带 | 客户端要发 Accept-Encoding: gzip |
用户第一次访问网站,下载了 HTML、CSS、JS、图片。第二次访问时,如果这些文件没变,为什么还要再传一遍?
通过expires 指令,Nginx可以在响应头里告诉浏览器:"这个文件 30 天内不会变,直接用本地缓存就行。"这样浏览器就不发请求了,服务器也不用传输文件。
| 写法 | 含义 |
|---|---|
| expires off | 不设缓存头(默认) |
| expires epoch | 设为 1970 年(即不缓存) |
| expires max | 设为 2037 年(即永久缓存) |
| expires 1h | 1 小时 |
| expires 1d | 1 天 |
| expires 30d | 30 天 |
| expires 1y | 1 年 |
| expires @12h30m | 到今天 12:30 过期 |
现代前端构建工具(Webpack/Vite)会在文件名里加 hash,比如app.a3f5b2.js。文件内容一变,hash 就变,文件名就变,浏览器自然会重新下载。
这种情况下可以放心地加immutable:
add_header Cache-Control "public, immutable";
immutable 告诉浏览器:"这个文件永远不会变,连验证请求都不用发。"能省掉大量 304 Not Modified 请求。
💡 提示: 只有文件名带 hash 的场景才能用 immutable。如果文件名是 style.css 这种固定名,用了 immutable 后用户改了 CSS 也看不到更新(只能强刷)。
第一次请求(本地无缓存)
前面的 Gzip和浏览器缓存都是"客户端侧"优化。如果后端应用(PHP-FPM、Python、Node.js)每次都要查数据库渲染页面,即使浏览器缓存了,新用户第一次访问还是慢。
fastcgi_cache 是 Nginx 把后端的响应缓存到本地磁盘/内存。下一个用户请求同一个页面时,Nginx 直接返回缓存,后端完全不用处理。
没有 fastcgi_cache 有fastcgi_cache
用户→ Nginx → PHP-FPM → 数据库 用户 → Nginx → 命中缓存 → 直接返回
↑ ↑ ↑
每次都要走完整链路 后端完全不用处理
10 个用户 = 10 次数据库查询 10 个用户 = 1 次数据库查询
通过add_header X-Cache-Status $upstream_cache_status 可以看到缓存命中情况:
| 状态 | 含义 |
|---|---|
| MISS | 未命中,请求转发到后端,响应被缓存 |
| HIT | 命中缓存,直接返回缓存内容 |
| BYPASS | 跳过缓存(匹配了 fastcgi_cache_bypass ) |
| EXPIRED | 缓存已过期,请求转发到后端,响应被重新缓存 |
| STALE | 返回了过期缓存(后端不可用时的兜底) |
| UPDATING | 正在更新缓存,返回旧缓存 |
| REVALIDATED | 通过条件请求验证缓存仍有效 |
⚠️ 注意: fastcgi_cache 只适用于 fastcgi_pass 后端(PHP-FPM 等)。如果后端是 Node/Python 走 proxy_pass,需要用 proxy_cache,语法几乎一样,把 fastcgi 换成 proxy 即可。
如果后端不是PHP-FPM 而是普通的 HTTP 服务(Node.js/Python/Go),用的是proxy_pass,那对应的就是 proxy_cache。
语法和fastcgi_cache 几乎一模一样,只是把前缀从 fastcgi 换成 proxy:
| 对比项 | fastcgi_cache | proxy_cache |
|---|---|---|
| 适用后端 | PHP-FPM ( fastcgi_pass ) | HTTP 服务( proxy_pass ) |
| 配置前缀 | fastcgi_ | proxy_ |
| 缓存路径指令 | fastcgi_cache_path | proxy_cache_path |
| 缓存 key | fastcgi_cache_key | proxy_cache_key |
| 缓存状态 | $upstream_cache_status | $upstream_cache_status |
| 清除模块 | ngx_cache_purge | ngx_cache_purge |
💡 提示: 两套缓存不能混用。proxy_pass 配 fastcgi_cache 是不生效的,反之亦然。
Nginx 每次服务静态文件请求,都要经历:打开文件 → 读取元数据 → 读文件内容 → 关闭文件。open_file_cache 把文件描述符和元数据缓存起来,下次直接用,省掉 open() 系统调用。
| 指令 | 作用 |
|---|---|
| max=1000 | 最多缓存 1000 个文件描述符,如果文件数超过则采用 LRU 淘汰 |
| inactive=20s | 20 秒内没被访问就清除 |
| open_file_cache_valid 30s | 每 30 秒检查一次文件是否变更 |
| open_file_cache_min_uses 2 | 至少被访问 2 次才缓存 |
| open_file_cache_errors on | 连文件不存在的错误也缓存(防止频繁探测) |
💡 提示: open_file_cache 对静态文件服务(CDN、图片站、文件下载站)效果明显,对动态内容(全部走 proxy_pass 的)几乎没有帮助。
| worker_connections 值 | 适合场景 |
|---|---|
| 512 | 小流量站 |
| 1024 | 中等流量(默认) |
| 4096 | 高并发 |
| 10240 | 超高并发(需配合 ulimit ) |
最大并发连接数= worker_processes × worker_connections
⚠️ 注意: 反向代理模式下,每个用户请求会占用 2 个连接(一个对客户端,一个对后端),所以实际最大用户数 = worker_processes × worker_connections / 2。worker_connections 调大了,别忘了同步调大worker_rlimit_nofile。
worker_connections 调大了,但 Linux 默认每个进程最多打开 1024 个文件描述符,会成为瓶颈:
| 对比项 | sendfile off | sendfile on |
|---|---|---|
| 数据路径 | 磁盘 → 内核 → 用户 → 内核 → 网卡 | 磁盘 → 内核 → 网卡 |
| 内存拷贝 | 2 次 | 0 次 |
| CPU 占用 | 高 | 低 |
| 适合场景 | 不推荐 | 静态文件服务必开 |
| 指令 | 作用 | 适合场景 |
|---|---|---|
| tcp_nopush on | 把多个小包合并成一个大包再发 | 大文件传输(配合 sendfile ) |
| tcp_nodelay on | 禁用 Nagle 算法,小包立即发 | 实时通信( WebSocket/SSH ) |
看起来矛盾——一个要合并包,一个要立即发。实际上 Nginx 会根据情况自动切换:传输大文件时用tcp_nopush 合并,传输完毕后用 tcp_nodelay 立即发完最后一个包,两个都开就对了。
http {
keepalive_timeout 65;
keepalive_requests 1000;
}
| 指令 | 作用 | 推荐值 |
|---|---|---|
| keepalive_timeout 65 | 客户端 keepalive 连接保持 65 秒 | 30-65 |
| keepalive_requests 1000 | 一个 keepalive 连接最多处理 1000 个请求 | 100-1000 |
💡 提示: keepalive_timeout 设太短(如 5 秒),用户浏览网页时连接频繁断开重建;设太长(如300 秒),大量空闲连接占用内存。65 秒是平衡点。
| 场景 | client_max_body_size 推荐值 |
|---|---|
| 纯网页(无上传) | 1m |
| 普通网站(头像上传) | 5m |
| 文件分享站 | 100m-1g |
| 视频上传 | 2g |
如果前端有CDN 或负载均衡,client_max_body_size 需要在所有层一致,否则可能被 CDN 拦截。
💡 提示: 配置改完后一定要走三部曲:sudo nginx -t → sudo nginx -s reload → 用 curl -I 验证效果。
# 打开浏览器访问
https://pagespeed.web.dev/analysis?url=https://example.com
输入网址,它会给出详细的性能评分和优化建议。不过 PageSpeed 在国内可能访问不稳定,替代方案可以用百度站长平台的"网站测速"功能或阿里云的"性能测试"服务。不是所有优化项都需要开,根据场景选择:
| 场景 | 必开项 | 可选项 |
|---|---|---|
| 纯静态站 | Gzip + expires + sendfile | open_file_cache |
| 反向代理站 | Gzip + proxy_cache + 缓冲区调优 | tcp_nopush |
| PHP-FPM 站 | Gzip + fastcgi_cache + expires | open_file_cache |
| API 网关 | Gzip + 缓冲区调优 | proxy_cache (注意 POST 不缓存) |
| 文件下载站 | sendfile + tcp_nopush | Gzip (对已压缩文件没用) |
| WebSocket | tcp_nodelay + keepalive_timeout | 不开 Gzip |
| 可能原因 | 检查方法 |
|---|---|
| 文件类型没在 gzip_types 里 | 检查 Content-Type |
| 文件小于 gzip_min_length | 用 curl -s url |
| 请求头没带 Accept-Encoding | 确认客户端发了这个头 |
| 配置没 reload | sudo nginx -s reload |
| 在 server 块里被覆盖了 | 检查有没有 gzip off |
| 可能原因 | 检查方法 |
|---|---|
| fastcgi_cache_bypass 条件命中 | 检查 $skip_cache 的判断逻辑 |
| 后端返回了 Cache-Control: no-cache | curl -I 看后端响应头 |
| 后端返回了 Set-Cookie | 带 Cookie 的响应默认不缓存 |
| 缓存目录权限不对 | ls -la /var/cache/nginx/ 看 www-data 是否可写 |
| 缓存 key 冲突 | 检查 fastcgi_cache_key 是否包含足够信息 |
| 问题 | 解决方法 |
|---|---|
| 用户 A 看到了用户 B 的数据 | 缓存 key 加上用户标识,或带 Cookie 的请求不缓存 |
| 登录页面被缓存了 | location /login 单独配 fastcgi_no_cache 1 |
| API 返回了旧数据 | 手动清除缓存,或缩短 fastcgi_cache_valid 时间 |
| POST 结果被缓存了 | 确认 $request_method = POST 时设 $skip_cache 1 |
🚨 警告: 缓存用户私有数据是严重的安全问题。登录后的个人页面、购物车、支付信息绝对不能缓存。如果不确定,宁可不开缓存。
| 可能原因 | 解决方法 |
|---|---|
| 系统文件描述符限制 | 设置 worker_rlimit_nofile 65535 |
| 系统端口范围限制 | sysctl net.ipv4.ip_local_port_range 查看并调大 |
| 后端处理太慢 | 优化后端应用,加机器 |
| 网络带宽瓶颈 | 监控网卡流量, iftop -n 查看 |
除了 Nginx自身配置,Linux 内核参数也影响性能:
⚠️ 注意: 内核参数改动是全局的,会影响所有服务。如果服务器上还跑了数据库/Redis 等,调整前先了解各参数的影响。
Gzip速查
| 指令 | 推荐值 | 作用 |
|---|---|---|
| gzip on | — | 开启压缩 |
| gzip_comp_level | 5-6 | 压缩级别 |
| gzip_min_length | 1k | 最小压缩大小 |
| gzip_types | 文本类型全包含 | 压缩的文件类型 |
| gzip_vary | on | 添加 Vary 头 |
缓存速查
| 类型 | 指令 | 适用场景 |
|---|---|---|
| 浏览器缓存 | expires | 静态文件 |
| fastcgi_cache | fastcgi_cache_path | PHP-FPM |
| proxy_cache | proxy_cache_path | HTTP 反向代理 |
| open_file_cache | open_file_cache | 静态文件服务 |
Worker速查
| 指令 | 推荐值 | 作用 |
|---|---|---|
| worker_processes | auto | 匹配 CPU 核心数 |
| worker_connections | 4096 | 每进程最大连接数 |
| worker_rlimit_nofile | 65535 | 文件描述符限制 |
| multi_accept | on | 一次接受所有新连接 |
网络传输速查
| 指令 | 推荐值 | 作用 |
|---|---|---|
| sendfile | on | 零拷贝传输 |
| tcp_nopush | on | 大文件合并发送 |
| tcp_nodelay | on | 小包立即发送 |
| keepalive_timeout | 65 | keepalive 超时 |
| server_tokens | off | 隐藏版本号 |
验证命令速查
| 命令 | 作用 |
|---|---|
| curl -I -H "Accept-Encoding: gzip" URL | 验证 Gzip |
| curl -I URL | 查看缓存头 |
| curl -I URL 两次看 X-Cache-Status | 验证代理缓存 |
| ab -n 100 -c 10 URL | 压力测试 |
| iftop -n | 查看网络流量 |
| htop | 查看 Nginx 进程 CPU/ 内存 |
小结
Nginx 性能优化不复杂,按优先级来:
Gzip****压缩——改几行配置,带宽直接砍 60%+,零成本
静态文件缓存——加一行 expires 30d,回访速度飞快
proxy_cache / fastcgi_cache——后端响应缓存,减轻后端压力
Worker****调优——auto + 4096 + 65535,高并发基础
网络传输——sendfile + tcp_nopush + tcp_nodelay,三个全开
记住一个原则:先开 Gzip 和 expires(收益最大),再上 proxy_cache(收益次之),最后调 worker 和内核参数(边际收益递减)。
💡 提示: 优化是持续过程,不是一次调完就永远不用管了。随着流量增长,定期用 ab 压测、用 htop 看资源占用、用 curl 验证缓存命中率,及时调整配置。
下篇预告: 《Nginx 安全加固》——限制速率防刷、封禁恶意 IP、隐藏敏感信息、防 DDoS 基础配置,让 Nginx 不仅快,还安全。
# 用 curl 检查响应头
curl -I -H "Accept-Encoding: gzip" https://example.com
# 看 Content-Encoding 是否为 gzip
# 正常输出:
# HTTP/1.1 200 OK
# Content-Encoding: gzip ← 这行说明 Gzip 生效了
# Content-Type: text/html
# Vary: Accept-Encoding# /etc/nginx/conf.d/example.conf
server {
listen 443 ssl;
server_name example.com;
# HTML 文件——不缓存或短缓存
# HTML 经常更新,缓存久了用户看不到新内容
location ~ \.html$ {
root /var/www/example;
expires 5m;
add_header Cache-Control "public, must-revalidate";
}
# CSS / JS——长缓存(文件名带 hash 时)
location ~ \.(css|js)$ {
root /var/www/example;
expires 30d;
add_header Cache-Control "public, immutable";
# 如果不用 immutable,至少也要配 max-age 和 etag,让浏览器缓存生效
}
# 图片——长缓存
location ~ \.(jpg|jpeg|png|gif|webp|ico|svg)$ {
root /var/www/example;
expires 30d;
add_header Cache-Control "public";
}
# 字体文件——长缓存
location ~ \.(woff|woff2|ttf|otf|eot)$ {
root /var/www/example;
expires 1y;
add_header Cache-Control "public";
}
}curl -I https://example.com/style.css
# 看 Cache-Control 和 Expires 头
# 第二次请求(带条件验证)
curl -I -H "If-Modified-Since: Tue, 07 Jul 2026 00:00:00 GMT" https://example.com/style.css
# 如果文件没变,返回 304 Not Modified**第一步:定义缓存区域(http 块)**
# 如果目录不存在
sudo mkdir -p /var/cache/nginx/fastcgi && sudo chown www-data:www-data /var/cache/nginx/fastcgi
# /etc/nginx/nginx.conf
http {
# fastcgi_cache 缓存路径
# /var/cache/nginx/fastcgi 缓存目录
# levels=1:2 目录层级
# keys_zone=FASTCGI:100m 共享内存名称和大小(100MB 可存约 80 万个 key)
# max_size=1g 磁盘缓存最大 1GB
# inactive=60m 60 分钟没人访问就自动清理
# use_temp_path=off 临时文件直接写到缓存目录
fastcgi_cache_path /var/cache/nginx/fastcgi
levels=1:2
keys_zone=FASTCGI:100m
max_size=1g
inactive=60m
use_temp_path=off;
# 缓存 key 的定义
# 用请求方法 + Host + URI 作为唯一标识
fastcgi_cache_key "$scheme$request_method$host$request_uri";
# 后端返回这些状态码时缓存
fastcgi_cache_valid 200 301 302 10m;
fastcgi_cache_valid 404 1m;
}
**第二步:在location 里启用缓存**
# /etc/nginx/conf.d/example.conf
server {
listen 443 ssl;
server_name example.com;
location ~ \.php$ {
root /var/www/example;
# 开启缓存,引用上面定义的区域名
fastcgi_cache FASTCGI;
# 缓存有效期(覆盖 http 块的全局设置)
fastcgi_cache_valid 200 10m;
fastcgi_cache_valid 404 1m;
# 哪些情况不缓存,下面的 $skip_cache 变量定义在后面,它的作用是指定哪些情况不缓存
fastcgi_cache_bypass $skip_cache; # 决定是否跳过读取缓存
fastcgi_no_cache $skip_cache; # 决定是否跳过写入缓存
# POST 请求和带查询参数的请求不缓存
set $skip_cache 0;
if ($request_method = POST) { set $skip_cache 1; }
if ($query_string != "") { set $skip_cache 1; }
# 添加响应头,标记是否命中缓存(调试用)
add_header X-Cache-Status $upstream_cache_status;
# fastcgi 参数
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}# 验证缓存是否生效
curl -I https://example.com/page.php
# 第一次:X-Cache-Status: MISS(未命中,从后端取)
# 第二次:X-Cache-Status: HIT (命中缓存)
💡 **提示:** 上线 fastcgi_cache 后,务必在生产环境用 curl -I 多请求几次,观察 X-Cache-Status 从 MISS 变成 HIT。如果一直是 MISS,说明缓存没生效,检查 fastcgi_cache_bypass 条件。**手动清除(全部清掉):**
# 停止 Nginx(避免缓存文件被同时读写)
sudo systemctl stop nginx
# 删除缓存目录内容
sudo rm -rf /var/cache/nginx/fastcgi/*
# 启动 Nginx
sudo systemctl start nginx
**选择性清除(需要ngx_cache_purge 模块):**
# 安装带 purge 模块的 Nginx(需要编译安装)
# Debian/Ubuntu 上可以装 nginx-extras
sudo apt install nginx-extras
# 配置清除路由
location ~ /purge(/.*) {
allow 127.0.0.1; # 只允许本机清除
deny all;
fastcgi_cache_purge FASTCGI "$scheme$request_method$host$1";
}
# 清除 /page.php 的缓存
curl http://127.0.0.1/purge/page.php# http 块
http {
proxy_cache_path /var/cache/nginx/proxy
levels=1:2
keys_zone=PROXY:50m
max_size=500m
inactive=30m
use_temp_path=off;
}
# server / location块
server {
location /api/ {
proxy_pass http://127.0.0.1:3000;
proxy_cache PROXY;
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
proxy_cache_bypass $skip_cache;
proxy_no_cache $skip_cache;
add_header X-Cache-Status $upstream_cache_status;
set $skip_cache 0;
if ($request_method = POST) { set $skip_cache 1; }
if ($http_authorization != "") { set $skip_cache 1; }
}
}
keys_zone=50m 是内存中缓存索引的大小,max_size=500m 是磁盘缓存总大小。# http 块
http {
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}# /etc/nginx/nginx.conf
# 方式一:手动指定
worker_processes 4;
# 方式二:自动匹配 CPU 核心数(推荐)
worker_processes auto;
auto 会根据 CPU 核心数自动设置,2 核就开 2 个 worker,8 核开 8 个,这是最优配置。# 查看当前限制
ulimit -n
# 输出:1024(默认值)
# 提高 Nginx 的限制
# 在 /etc/nginx/nginx.conf最上面加
worker_rlimit_nofile 65535;
# 同时修改系统限制
# /etc/security/limits.conf 加两行
# * soft nofile 65535
# * hard nofile 65535
# 重启 Nginx 生效
sudo systemctl restart nginx
# 验证
cat /proc/$(cat /var/run/nginx.pid)/limits | grep "open files"
# 输出:Max open files 65535 65535# 让 Nginx worker 进程以更高优先级运行
# 值越低优先级越高(-20 最高,19 最低)
worker_priority -5;
💡 **提示:** 一般不用改。只有服务器上跑了多个服务(数据库 + Nginx + Redis),想让 Nginx 优先拿到CPU 时才调。http {
sendfile on;
}
sendfile 让 Nginx 用零拷贝方式传输文件。不开时,文件数据要从磁盘 →内核空间 → 用户空间 → 内核空间 → 网卡;开了 sendfile 后,直接从磁盘→ 内核空间 → 网卡,省掉两次内存拷贝。sendfile 只对 Nginx 直接提供静态文件(root)时有效,proxy_pass 场景不涉及。http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
}当 Nginx 作为反向代理时,后端响应会被先缓冲到 Nginx,再发给客户端。如果缓冲区太小,响应会被写到磁盘临时文件,性能暴跌。
http {
# 代理缓冲区
proxy_buffering on;
proxy_buffer_size 4k; # 响应头缓冲区
proxy_buffers 8 4k; # 响应体缓冲区:8 个 4KB 块
proxy_busy_buffers_size 8k; # 忙时缓冲区大小
proxy_max_temp_file_size 0; # 禁止写临时文件(缓冲区满且禁止写临时文件时,Nginx 会返回 502 )
}
⚠️ **注意:** proxy_max_temp_file_size 0 禁止写临时文件,如果后端返回超大响应(如文件下载),会导致 502。文件下载场景要设大一点:proxy_max_temp_file_size 1024m。http {
client_body_buffer_size 8k; # 客户端请求体缓冲区
client_max_body_size 20m; # 最大上传文件大小
client_header_buffer_size 1k; # 请求头缓冲区
large_client_header_buffers 4 8k; # 大请求头缓冲区
}把以上所有优化项整合到一份配置文件里:
# /etc/nginx/nginx.conf
# ===== 全局块 =====
user www-data;
worker_processes auto;
worker_priority -5;
worker_rlimit_nofile 65535;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log warn;
# ===== events 块 =====
events {
worker_connections 4096;
multi_accept on; # 一次接受所有新连接
use epoll; # Linux 用 epoll 事件模型
}
# ===== http 块 =====
http {
# 检查是否启用了 Gzip
curl -I -H "Accept-Encoding: gzip" https://example.com/style.css
# 期望看到:
# Content-Encoding: gzip
# Vary: Accept-Encoding# 浏览器缓存
curl -I https://example.com/style.css
# 期望看到:
# Cache-Control: public, immutable
# Expires: Wed, 06 Aug 2026 ...
# 代理缓存
curl -I https://example.com/api/data
# 第一次:X-Cache-Status: MISS
# 第二次:X-Cache-Status: HIT# 不压缩
curl -s https://example.com/style.css | wc -c
# 输出:82034
# 压缩后
curl -s -H "Accept-Encoding: gzip" https://example.com/style.css | wc -c
# 输出:16384
# 压缩率:(82034 - 16384) / 82034 = 80%# 安装 ab
sudo apt install apache2-utils
# 压测(100 个请求,10 并发)
ab -n 100 -c 10 https://example.com/
# HTTPS 压测建议并发数不要超过 50,否则可能触发 SSL 握手失败
# 关注指标:
# Requests per second 每秒处理请求数(越高越好)
# Time per request 每个请求耗时(越低越好)
# Transfer rate 传输速率# /etc/sysctl.d/99-nginx.conf
# TCP 连接相关
net.core.somaxconn = 65535 # 监听队列长度
net.ipv4.tcp_max_syn_backlog = 65535 # SYN 队列长度
net.ipv4.tcp_fin_timeout = 15 # FIN-WAIT-2 状态超时
net.ipv4.tcp_tw_reuse = 1 # 复用 TIME_WAIT 连接
# 文件描述符
fs.file-max = 2097152 # 系统级最大文件描述符
# 端口范围
net.ipv4.ip_local_port_range = 1024 65535
# 网络缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 应用配置
sudo sysctl -p /etc/sysctl.d/99-nginx.conf