⚡ Nginx 优化指南:让你的网站快如闪电
⚡ Nginx 优化指南:让你的网站快如闪电
之前我们讲了 Gunicorn 的优化,今天轮到 Nginx 了!如果说 Gunicorn 是发动机,那 Nginx 就是变速箱 —— 调教好了,马力全开!🏎️
🎯 Nginx 能做什么优化?
想象一下:
text
1 2 3 4 5 6 7 8 9 | 未优化的 Nginx: - 就像堵车的高速公路 🚗🚗🚗 - 请求排队,响应慢 - 资源浪费 优化后的 Nginx: - 就像空旷的高速公路 🏎️💨 - 并行处理,飞快响应 - 资源利用率高 |
🔧 第一步:基础配置优化
Worker 进程数
nginx.conf
nginx
1 2 3 4 5 6 7 8 9 10 | # 自动匹配 CPU 核心数 worker_processes auto; # 或者手动指定 # worker_processes 4; # 每个 Worker 的最大连接数 events { worker_connections 1024; } |
计算公式:
text
1 2 | 最大并发数 = worker_processes × worker_connections 例如:4 × 1024 = 4096 并发 |
选择合适的 Event 模型
nginx
1 2 3 4 5 6 7 8 9 10 | events { # Linux 使用 epoll use epoll; # 每个 Worker 的连接数 worker_connections 2048; # 允许同时接受多个连接 multi_accept on; } |
不同系统的最佳模型:
| 系统 | Event 模型 |
|---|---|
| Linux | epoll |
| FreeBSD | kqueue |
| MacOS | kqueue |
| Windows | select |
⚡ 第二步:HTTP 核心优化
启用 HTTP/2
nginx
1 2 3 4 5 6 7 8 | server { listen 443 ssl http2; listen [::]:443 ssl http2; # SSL 证书配置 ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; } |
HTTP/2 的优势:
- ✅ 多路复用(一个连接多个请求)
- ✅ 头部压缩(减少传输量)
- ✅ 服务器推送(主动发送资源)
优化 Buffer
nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 | http { # 客户端请求 Body 大小 client_max_body_size 16M; # 缓冲区大小 client_body_buffer_size 128k; # 代理缓冲 proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; proxy_busy_buffers_size 8k; } |
Buffer 大小建议:
nginx
1 2 3 4 5 6 7 8 | # 小文件为主 proxy_buffers 8 4k; # 32KB # 大文件为主 proxy_buffers 4 8k; # 32KB # 不确定 proxy_buffers 8 16k; # 128KB |
超时设置
nginx
1 2 3 4 5 6 7 8 9 10 11 12 | http { # 客户端超时 client_body_timeout 12; client_header_timeout 12; keepalive_timeout 65; send_timeout 10; # 代理超时 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } |
建议值:
| 场景 | keepalive_timeout | 说明 |
|---|---|---|
| 高流量 | 15-30 | 减少连接占用 |
| 普通 | 65 | 默认值 |
| API 服务 | 300 | 长连接 |
💾 第三步:缓存优化
静态文件缓存
nginx
1 2 3 4 5 6 7 8 9 10 11 12 | # 图片、CSS、JS location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 30d; add_header Cache-Control "public, immutable"; access_log off; } # HTML 文件 location ~* \.html$ { expires 1h; add_header Cache-Control "public"; } |
缓存策略:
| 资源类型 | 过期时间 | 策略 |
|---|---|---|
| 图片/字体 | 30 天 | immutable |
| CSS/JS | 7 天 | public |
| HTML | 1 小时 | public |
| API | 不缓存 | no-cache |
代理缓存
nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # 定义缓存路径 proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=blog_cache:10m max_size=1g inactive=60m use_temp_path=off; server { location / { # 启用缓存 proxy_cache blog_cache; # 缓存键 proxy_cache_key "$scheme$request_method$host$request_uri"; # 200 状态码缓存 10 分钟 proxy_cache_valid 200 10m; # 其他状态码缓存 1 分钟 proxy_cache_valid any 1m; # 传递后端缓存头 proxy_pass http://127.0.0.1:5000; } } |
FastCGI 缓存(WordPress 等动态站点)
nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # 定义缓存 fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fastcgi:10m max_size=1g inactive=60m; server { location ~ \.php$ { fastcgi_cache fastcgi; fastcgi_cache_valid 200 10m; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_pass 127.0.0.1:9000; } } |
🗜️ 第四步:压缩优化
Gzip 压缩
nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | http { # 启用 Gzip gzip on; gzip_vary on; gzip_min_length 1024; gzip_comp_level 6; # 压缩文件类型 gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; # 排除已压缩文件 gzip_disable "msie6"; } |
压缩级别选择:
| 级别 | CPU 使用 | 压缩比 | 推荐场景 |
|---|---|---|---|
| 1-3 | 低 | 小 | 高流量,CPU 紧张 |
| 4-6 | 中 | 中 | 推荐(平衡) |
| 7-9 | 高 | 大 | 流量小,CPU 充足 |
Brotli 压缩(更高效)
需要安装 ngx_brotli 模块:
nginx
1 2 3 4 5 | http { brotli on; brotli_comp_level 6; brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml; } |
Brotli vs Gzip:
| 指标 | Brotli | Gzip |
|---|---|---|
| 压缩比 | 更好 | 一般 |
| 速度 | 稍慢 | 更快 |
| 兼容性 | 较新 | 广泛 |
🚀 第五步:连接优化
Keep-Alive
nginx
1 2 3 4 | http { keepalive_timeout 65; keepalive_requests 100; } |
建议配置:
nginx
1 2 3 4 5 6 7 | # 高并发场景 keepalive_timeout 30; keepalive_requests 1000; # 普通场景 keepalive_timeout 65; keepalive_requests 100; |
TCP 优化
nginx
1 2 3 4 5 | http { # 启用 TCP_NODELAY tcp_nodelay on; tcp_nopush on; } |
作用:
tcp_nodelay:立即发送小数据包tcp_nopush:合并发送数据包
🔒 第六步:安全优化
隐藏版本号
nginx
1 2 3 4 5 6 7 | http { # 隐藏 Nginx 版本 server_tokens off; # 或者自定义名称 more_set_headers "Server: MyWebServer"; } |
限制请求速率
nginx
1 2 3 4 5 6 7 8 9 10 11 | # 定义限流区域 limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; server { location /api/ { # 限制每秒 10 个请求 limit_req zone=api burst=20 nodelay; proxy_pass http://backend; } } |
参数说明:
rate=10r/s:每秒 10 个请求burst=20:突发 20 个请求nodelay:立即处理突发
IP 黑白名单
nginx
1 2 3 4 5 6 7 8 9 10 | # 允许的 IP allow 192.168.1.0/24; allow 10.0.0.0/8; # 拒绝其他所有 deny all; # 只拒绝特定 IP deny 1.2.3.4; deny 5.6.7.0/24; |
📊 第七步:日志优化
访问日志格式
nginx
1 2 3 4 5 6 7 8 9 | http { # 自定义日志格式 log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time'; access_log /var/log/nginx/access.log main; } |
关键指标:
$request_time:总请求时间$upstream_response_time:后端响应时间
条件日志记录
nginx
1 2 3 4 5 6 7 | # 只记录 4xx 和 5xx map $status $loggable { ~^[23] 0; default 1; } access_log /var/log/nginx/access.log main if=$loggable; |
日志缓冲
nginx
1 2 3 4 | http { # 缓冲 32KB,每 5 秒刷新 access_log /var/log/nginx/access.log main buffer=32k flush=5s; } |
🧪 第八步:性能测试
使用 Apache Bench
bash
1 2 3 4 5 | # 测试 1000 个请求,10 个并发 ab -n 1000 -c 10 http://localhost/ # 带 Cookie 测试 ab -n 1000 -C "session=xxx" http://localhost/ |
关键指标:
Requests per second:每秒请求数(越高越好)Time per request:平均响应时间(越低越好)
使用 wrk
bash
1 2 3 4 5 | # 10 线程,10 连接,运行 10 秒 wrk -t10 -c10 -d10s http://localhost/ # 使用 Lua 脚本 wrk -t10 -c10 -d10s -s post.lua http://localhost/ |
使用 Siege
bash
1 2 3 4 5 | # 并发 20,持续 30 秒 siege -c 20 -t 30S http://localhost/ # 模拟登录 siege -c 10 -H "Cookie: session=xxx" http://localhost/ |
🎯 实战案例
场景:博客首页优化
问题:首页加载需要 5 秒 😱
诊断:
bash
1 2 3 4 | # 分析日志 awk '{print $NF}' /var/log/nginx/access.log | sort -n | tail -10 # 发现:大量图片请求 > 2 秒 |
优化方案:
nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # 1. 启用缓存 location ~* \.(jpg|png|gif)$ { expires 30d; add_header Cache-Control "public, immutable"; } # 2. 启用 Gzip gzip on; gzip_types image/svg+xml; # 3. 代理缓存 proxy_cache blog_cache; proxy_cache_valid 200 10m; # 4. HTTP/2 listen 443 ssl http2; |
效果:
| 指标 | 优化前 | 优化后 | 提升 |
|---|---|---|---|
| 首屏时间 | 5s | 1.5s | 70% |
| 请求数 | 50 | 15 | 70% |
| 传输大小 | 2MB | 500KB | 75% |
📈 监控和维护
实时监控
bash
1 2 3 4 5 6 7 8 | # 监控访问日志 tail -f /var/log/nginx/access.log # 统计 QPS awk '{print $4}' /var/log/nginx/access.log | cut -d: -f2 | sort | uniq -c # 统计状态码 awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn |
性能分析工具
bash
1 2 3 4 5 | # nginx-vts-exporter(Prometheus 指标) https://github.com/hnlq715/nginx-vts-exporter # nginx-amplify(商业监控) https://www.nginx.com/nginx-amplify/ |
⚠️ 常见陷阱
1. Worker 设置过多
nginx
1 2 3 4 5 | # ❌ 错误:16 核 CPU 设置 100 个 Workers worker_processes 100; # ✅ 正确 worker_processes auto; # 自动匹配 |
2. Buffer 设置不当
nginx
1 2 3 4 5 6 | # ❌ 错误:Buffer 太大,浪费内存 client_body_buffer_size 100m; # ✅ 正确 client_body_buffer_size 128k; client_max_body_size 100m; # 大文件用磁盘 |
3. 缓存时间过长
nginx
1 2 3 4 5 6 7 8 9 | # ❌ 危险:HTML 缓存太久 location ~* \.html$ { expires 30d; # 内容更新后用户看不到 } # ✅ 正确 location ~* \.html$ { expires 1h; } |
📋 优化检查清单
- [ ] Worker 进程数 = CPU 核心数
- [ ] Worker 连接数 ≥ 1024
- [ ] 启用 HTTP/2
- [ ] 配置静态文件缓存
- [ ] 启用 Gzip 压缩
- [ ] 优化 Buffer 大小
- [ ] 配置合理的超时
- [ ] 隐藏版本号
- [ ] 限制请求速率
- [ ] 优化日志格式
- [ ] 性能测试验证
- [ ] 监控关键指标
🎉 总结
Nginx 优化的核心思想:
- 减少等待 → 并发处理
- 减少传输 → 启用压缩
- 减少计算 → 缓存结果
- 合理配置 → 平衡性能
记住:
"过早优化是万恶之源,但合理的配置是必不可少的!" 🎯
📚 延伸阅读
下期预告:HTTPS 完全指南,让你的网站更安全!🔒
0 人点赞
评论 (0)
暂无评论,快来抢沙发吧~
发表评论