Nginx 装完默认就能跑,但默认配置是「兼容一切」的保守值——worker 连接数 768、gzip 没开、静态资源不缓存,稍微来点并发就露怯。这篇把值得改的参数按「效果/风险」排出来,每条都说明白为什么。
一、全局层:worker 进程与连接
# /etc/nginx/nginx.conf
user www-data;
worker_processes auto; # 等于 CPU 核数,auto 即可
worker_rlimit_nofile 65535; # 每个 worker 的文件描述符上限
events {
worker_connections 10240; # 默认 768,明显不够
use epoll; # Linux 高并发标配
multi_accept on;
}
理论最大并发 = worker_processes × worker_connections,4 核机器就是 4 万+。两个配套动作别忘:
- 系统层放开限制:
/etc/security/limits.conf加www-data soft nofile 65535与 hard 同行。 - worker_connections 不是越大越好——每个连接吃内存,2GB 小机器别拍 10 万。
二、HTTP 层:这三行先开再说
http {
sendfile on; # 内核态直接发文件,省两次用户态拷贝
tcp_nopush on; # 配合 sendfile,整包发送
tcp_nodelay on; # 小包不等,交互型接口友好
keepalive_timeout 65; # 连接复用,默认 65s 其实可以
keepalive_requests 1000; # 默认 100,长连接别这么早断
server_tokens off; # 响应头不暴露 Nginx 版本
}
三、gzip:流量立减 60%–80%(按内容估算)
默认只压 text/html,其余全裸奔。补上:
gzip on;
gzip_vary on;
gzip_min_length 1024; # 太小的别压,CPU 不划算
gzip_comp_level 5; # 5 是性价比拐点,再高压不了多少
gzip_types text/plain text/css application/json application/javascript
application/xml image/svg+xml;
注意:图片(jpg/png/webp)不要压——它们本身已压缩,纯浪费 CPU;JSON 接口是收益最大的场景。
四、静态资源:让浏览器自己存
location ~* \.(css|js|png|jpg|jpeg|gif|webp|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off; # 静态资源日志没分析价值,关掉省 IO
}
带 hash 指纹的构建产物(app.a1b2c3.js)可以放心 immutable;不带指纹的用短一点的 expires 7d。
五、反向代理:几个必懂参数
upstream backend {
server 127.0.0.1:8080;
keepalive 32; # 到后端的长连接池
}
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1; # keepalive 的前提
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_next_upstream error timeout; # 后端挂了自动重试下一台
}
常见坑:proxy_set_header Connection "" 不写,upstream 的 keepalive 不生效,每次请求都重新 TCP 握手;后端拿到的 IP 全是 127.0.0.1,是因为没传 X-Real-IP。
六、限流防刷(一行顶一个防火墙规则)
# http 层定义:每个 IP 每秒 10 个请求,10 个突发队列
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /api/ {
limit_req zone=api burst=20 nodelay;
limit_req_status 429;
}
nodelay 表示突发配额立刻放行而不是匀速排队——不带它,用户体验是「请求被憋慢」;带上它是「放完 20 个再拒」,通常后者才是想要的。
七、其他值得做的小事
- 日志切割:
/etc/logrotate.d/nginx默认有,确认在跑,否则 access.log 一年几十 GB。 - 超时统一收紧:
client_body_timeout、client_header_timeout设 10s,慢连接占着 worker 不放也是资源。 - 隐藏目录:
location ~ /\.{ deny all; } 挡住.git、.env被下载——真发生过的事故。 - 改完配置永远
nginx -t再 reload;reload 是平滑的,不用停服务。
八、优化效果怎么验证
别凭感觉,用数据:压测前后各跑一次 curl -w 看耗时,或用本站的 HTTP/Ping 检测 和 HTTP 状态码查询 验证响应头里 gzip、Cache-Control、429 是否按预期生效。
相关工具:HTTP/Ping 检测 · HTTP 状态码查询 · HTTP 请求测试