Nginx 性能
约 3572 字大约 12 分钟
2025-10-31
工作进程数
worker_processes 用于设置 Nginx 的工作进程数。
控制 Nginx 的 并发处理能力,合理配置可在性能和资源消耗间取得最佳平衡。
## 最佳实践:让 Nginx 自动检测 CPU 核心数
worker_processes auto;## 根据 CPU 核心数手动设置
worker_processes 4; ## 4核CPU
worker_processes 8; ## 8核CPU
## 保留一个核心给系统进程
worker_processes 3; ## 4核CPU保留1核核心数检测方法
系统命令检测
# 查看物理 CPU 核心数
nproc --all
# 或
grep -c ^processor /proc/cpuinfo
# 查看 CPU 拓扑信息
lscpu
# 查看负载情况
uptime动态配置示例
## 根据系统核心数动态配置
worker_processes {{ ansible_processor_cores }}; ## Ansible 变量通用生产配置
## /etc/nginx/nginx.conf
## 自动检测 CPU 核心数(推荐)
worker_processes auto;
## 每个进程的文件描述符限制
worker_rlimit_nofile 65535;
## 事件模型配置
events {
## 每个工作进程的最大连接数
worker_connections 10240;
## 使用高效事件模型
use epoll;
## 允许同时接受多个连接
multi_accept on;
}最大连接数
worker_connections 决定了 单个 Nginx 工作进程能同时处理的最大连接数,直接影响服务的并发处理能力。
数字越大,能同时处理的连接越多。
内存占用计算
## 每个连接的内存开销计算:
## - 1个连接对象: ~232字节
## - 2个事件(read+write): ~96字节
## - 总计: ~328字节/连接
## 内存占用公式:
内存(MB) = worker_connections × 328 ÷ 1024 ÷ 1024
## 示例计算:
worker_connections 100000; ## 占用内存 ≈ 31MB
worker_connections 50000; ## 占用内存 ≈ 16MB
worker_connections 20000; ## 占用内存 ≈ 6MBNginx HTTP/2
HTTP/2 通过 多路复用、头部压缩、服务器推送 等特性,显著提升 Web 应用性能。
启用 HTTP/2
server {
listen 443 ssl http2; ## 关键:在 SSL 基础上启用 HTTP/2
server_name example.com;
ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/private.key;
## HTTP/2 必需的安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
...
}HTTP 到 HTTPS 重定向
## 强制使用 HTTPS + HTTP/2
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri; ## 重定向到 HTTPS
}连接优化
server {
listen 443 ssl http2;
## HTTP/2 特定优化
http2_max_field_size 16k; ## 头部字段最大大小
http2_max_concurrent_streams 128; ## 并发流数量
http2_max_requests 1000; ## 连接最大请求数
http2_recv_timeout 30s; ## 接收超时
## 保持连接活跃
keepalive_timeout 30s;
keepalive_requests 1000;
}资源推送(Server Push)
server {
listen 443 ssl http2;
location = /index.html {
http2_push /style.css; ## 推送关键 CSS
http2_push /app.js; ## 推送关键 JS
}
location /static/ {
## 静态资源适合推送
add_header Link "</static/logo.png>; as=image; rel=preload";
}
}现代加密套件
server {
listen 443 ssl http2;
## 必需的安全配置
ssl_protocols TLSv1.2 TLSv1.3;
## 现代加密套件(兼容 HTTP/2)
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
## 增强安全性
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
}验证 HTTP/2 是否生效
# 使用 curl 检查
curl -I --http2 https://example.com
# 使用 nghttp2 工具
nghttp -nv https://example.com
# 浏览器开发者工具查看
# Network → Protocol 列显示 h2配置状态监控
server {
listen 443 ssl http2;
location /nginx-status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}兼容性处理
- 自动回退到 HTTP/1.1
- 不支持 HTTP/2 的客户端会自动使用 HTTP/1.1
- 无需特殊配置,完全向后兼容
性能收益
- 多路复用:消除队头阻塞
- 头部压缩:减少传输开销
- 服务器推送:预加载关键资源
- 二进制协议:解析更高效
通过简单启用 HTTP/2,即可获得显著的性能提升,且完全向后兼容。
维护 SSL 会话
通过会话复用减少 SSL/TLS 握手开销,显著提升 HTTPS 连接性能。
http {
## 共享会话缓存(所有工作进程共享)
ssl_session_cache shared:NGX_SSL_CACHE:10m; ## 🔄 10MB 共享缓存
ssl_session_timeout 12h; ## ⏰ 会话有效期 12 小时
server {
listen 443 ssl http2;
server_name example.com;
## 继承全局 SSL 会话配置
ssl_session_tickets off; ## 🚫 禁用会话票据(安全)
ssl_buffer_size 1400; ## 📦 优化 TLS 记录大小
ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/private.key;
...
}
}会话缓存大小计算
## 缓存容量估算:
## - 每个会话约 2.5KB
## - 10MB 缓存 ≈ 4,000 个会话
## - 20MB 缓存 ≈ 8,000 个会话
## - 50MB 缓存 ≈ 20,000 个会话
ssl_session_cache shared:SSL_CACHE:20m; ## 支持约 8,000 个并发会话超时策略优化
## 平衡安全性和性能
ssl_session_timeout 4h; ## 🕐 一般场景:4小时
ssl_session_timeout 1d; ## 🕐 高访问频率:1天
ssl_session_timeout 30m; ## 🕐 高安全要求:30分钟禁用会话票据
ssl_session_tickets off; ## ✅ 推荐:避免会话票据安全风险
## 原因:
## - 会话票据可能长期有效
## - 服务器不主动清理票据密钥
## - 减少密钥泄露的影响范围前向安全性保障
ssl_session_tickets off;
ssl_session_cache shared:SSL_CACHE:10m;
## 使用临时密钥交换
ssl_ecdh_curve X25519:secp384r1;
## 定期轮换会话密钥
## (通过重启 Nginx 或重新加载配置)缓冲区优化
## 优化 TLS 记录大小(避免 IP 分片)
ssl_buffer_size 1400; ## 📊 适应标准 MTU(1500 - 头部开销)
## 对于高延迟网络可适当增大
ssl_buffer_size 4k; ## 📊 高延迟链路优化会话缓存策略
## 多域名共享配置
http {
ssl_session_cache shared:GLOBAL_SSL_CACHE:50m;
ssl_session_timeout 8h;
ssl_session_tickets off;
## 所有虚拟主机继承相同配置
}分级超时策略
## 内部 API(短超时)
server {
server_name api.internal.com;
ssl_session_timeout 1h; ## 内部服务 1 小时
}
## 用户面向服务(中等超时)
server {
server_name app.example.com;
ssl_session_timeout 4h; ## 用户会话 4 小时
}
## 合作伙伴接口(长超时)
server {
server_name partner.example.com;
ssl_session_timeout 24h; ## 合作伙伴 24 小时
}性能收益
- 减少 CPU 消耗:避免重复的 SSL 握手计算
- 降低连接延迟:复用会话节省握手时间
- 提升并发能力:减少新连接建立开销
- 改善用户体验:更快的内容加载速度
通过合理配置 SSL 会话缓存,可以在保持安全性的同时,显著提升 HTTPS 服务的性能和用户体验。
server_name 匹配优化
Nginx 使用三层哈希表进行服务器名称匹配,不同匹配方式的性能差异显著。
三层哈希表结构
## 性能从高到低:
## 1. 精确名称哈希表 (最快)
## 2. 前缀通配符哈希表 (*.example.com)
## 3. 后缀通配符哈希表 (example.*)
## 4. 正则表达式 (最慢,顺序匹配)性能对比配置
## ✅ 最优配置:精确名称
server {
listen 80;
server_name example.com www.example.com; ## 🚀 精确匹配,性能最佳
...
}
## ⚠️ 次优配置:通配符
server {
listen 80;
server_name *.example.com; ## 🐢 通配符搜索,性能中等
...
}
## ❌ 最差配置:正则表达式
server {
listen 80;
server_name ~^www\.example\.(com|org)$; ## 🐌 正则匹配,性能最差
...
}显式列出精确名称
## ✅ 推荐:显式列出所有域名
server {
listen 80;
server_name example.com www.example.com blog.example.com;
location / {
root /var/www/example;
...
}
}
## ❌ 避免:使用简化形式
server {
listen 80;
server_name .example.com; ## 隐含 *.example.com example.com
...
}默认服务器配置
## 捕获所有未匹配的请求
server {
listen 80 default_server;
server_name _; ## 特殊名称,匹配任意主机名
return 444; ## 关闭连接
## 或跳转到主域名
# return 301 https://example.com$request_uri;
}IP 直接访问处理
## 处理直接通过 IP 访问的请求
server {
listen 80;
server_name ""; ## 空主机头
location / {
return 444; ## 安全拒绝
## 或显示维护页面
# root /var/www/maintenance;
}
}避免使用 if 检查 server_name
在请求处理阶段使用 if 检查 $host 会导致每个请求都进行条件判断,造成不必要的性能开销。
低效配置:if 判断方式
server {
server_name domain.com www.domain.com;
## 问题:每个请求都要执行 if 判断
if ($host = www.domain.com) {
return 301 https://domain.com$request_uri;
}
... ## 其他配置
}高效配置:多 server 块方式
## 专用重定向服务器块
server {
server_name www.domain.com;
return 301 $scheme://domain.com$request_uri; ## 直接返回,无需判断
}
## 主服务器块
server {
server_name domain.com;
... ## 业务逻辑配置
}使用 $request_uri 避免正则表达式
使用 $request_uri 变量可以直接获取完整请求 URI,避免昂贵的正则表达式匹配和捕获操作。
低效配置:正则表达式方式
## 方式1:正则捕获组(性能最差)
rewrite ^/(.*)$ https://example.com/$1 permanent;
## 方式2:正则匹配 + 变量(仍有正则开销)
rewrite ^ https://example.com$request_uri? permanent;高效配置:直接使用变量
## 直接使用 $request_uri(性能最佳)
return 301 https://example.com$request_uri;性能开销对比
正则表达式方式:
请求 → 正则引擎编译 → 模式匹配 → 捕获组处理 → 字符串拼接 → 返回
$request_uri 方式:
请求 → 变量读取 → 字符串拼接 → 返回域名迁移重定向
## 旧域名到新域名(保留完整路径)
server {
server_name old-example.com www.old-example.com;
return 301 https://new-example.com$request_uri; ## 🚀 高效重定向
}
## 多域名统一标准化
server {
server_name example.net example.org;
return 301 https://example.com$request_uri; ## 🔄 统一主域名
}HTTP 到 HTTPS 升级
## 强制 HTTPS(保留原始 URI)
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri; ## 🔒 安全升级
}
## 特定路径强制 HTTPS
server {
listen 80;
server_name example.com;
location /secure/ {
return 301 https://$host$request_uri; ## 🎯 精确重定向
}
}路径结构调整
## 整个站点路径前缀变更
server {
server_name example.com;
return 301 https://example.com/new-prefix$request_uri; ## 📁 路径迁移
}
## 保留查询参数的重定向
location /old-app/ {
return 301 /new-app$request_uri; ## 🔗 完整路径传递
}try_files
try_files 提供了一种高效、声明式的文件存在性检查方式,完全替代低效的 if -f 条件判断。
低效配置:if 判断方式
server {
root /var/www/example.com;
location /images {
## 问题:每个请求都执行文件系统检查
if (-f $request_filename) {
expires 30d;
break;
}
## 需要额外的错误处理
return 404;
}
}高效配置:try_files 方式
server {
root /var/www/example.com;
location /images {
## 优势:单次声明,自动处理所有情况
try_files $uri =404;
expires 30d; ## 仅在文件存在时应用
}
}try_files 语法详解
try_files file1 [file2 ...] fallback;常用模式
## 检查静态文件,不存在则返回 404
try_files $uri =404;
## 检查文件,不存在则尝试目录索引
try_files $uri $uri/ =404;
## 多级回退策略
try_files $uri $uri/ /fallback/index.html;实际应用场景
静态文件服务
server {
root /var/www/example.com;
location / {
## 检查文件 → 检查目录 → 返回 404
try_files $uri $uri/ =404; ## 完整的静态文件处理
}
location /assets/ {
## 静态资源带缓存头
try_files $uri =404;
expires 1y;
add_header Cache-Control "public, immutable"; ## 长期缓存
}
}SPA 前端路由
server {
root /var/www/spa-app;
location / {
## 文件不存在时返回 index.html(前端路由接管)
try_files $uri $uri/ /index.html; ## SPA 标准配置
}
location /static/ {
## 静态资源严格检查
try_files $uri =404;
expires max;
}
}多级回退策略
server {
root /var/www/application;
location / {
## 优先级:具体文件 → 压缩版本 → 通用处理
try_files $uri $uri.gz $uri/ @backend; ## 智能回退
}
location @backend {
## 最终回退到应用服务器
proxy_pass http://backend-server;
proxy_set_header Host $host;
}
}条件压缩文件服务
server {
root /var/www/example.com;
location / {
## 优先提供预压缩版本(节省 CPU)
try_files $uri.gz $uri $uri/ =404; ## 性能优化
}
location ~ \.gz$ {
## 设置正确的压缩文件头
add_header Content-Encoding gzip;
gzip off; ## 避免重复压缩
}
}使用 return 替代 rewrite
return 指令提供了一种更高效、更简洁的重定向方式,避免正则表达式匹配的开销。
低效配置:rewrite 方式
server {
## 问题:每个匹配的请求都需要正则处理
if ($host = api.domain.com) {
rewrite ^/(.*)$ http://example.com/$1 permanent; ## 正则开销
}
## 或者更复杂的正则
rewrite ^/old-path/(.*)$ /new-path/$1 permanent;
}高效配置:return 方式
server {
## 优势:直接返回,无正则开销
if ($host = api.domain.com) {
return 403; ## 立即返回状态码
}
## 或者使用变量进行重定向
return 301 https://domain.com$request_uri;
}return 指令语法详解
return code [text];
return code URL;
return URL;常用状态码
## 永久重定向
return 301 https://new-domain.com$request_uri;
## 临时重定向
return 302 /temporary-location;
## 客户端错误
return 403; ## 禁止访问
return 404; ## 未找到
## 服务器错误
return 500; ## 内部服务器错误
return 503; ## 服务不可用访问控制
## IP 黑名单
geo $block_ip {
default 0;
192.168.1.100 1;
10.0.0.50 1;
}
server {
location /admin/ {
if ($block_ip) {
return 403; ## 立即拒绝
}
## 正常处理
}
}
## User-Agent 过滤
server {
location / {
if ($http_user_agent ~* (bot|crawler|spider)) {
return 444; ## 静默关闭连接
}
}
}执行路径对比
rewrite 方式:
请求 → 正则编译 → 模式匹配 → 捕获组处理 → 内部重定向 → 响应
return 方式:
请求 → 立即响应(无额外处理)PCRE JIT 与精确位置匹配
作用:通过即时编译技术大幅提升正则表达式处理速度。
## 在 nginx.conf 的 main 上下文中开启
pcre_jit on;编译要求:
- 使用
--with-pcre-jit参数编译 Nginx - PCRE 库版本 ≥ 8.20 并启用 JIT 支持
- 系统 PCRE 库需编译时开启 JIT
效果:对使用正则的 location、rewrite、return 等指令有明显性能提升。
精确位置匹配优化
语法:location = /path
优势:精确匹配立即终止搜索,性能最优。
## 精确匹配 - 最高性能
location = / {
## 首页特殊处理
}
location = /api/v1 {
## API 端点精确匹配
}
## 前缀匹配 - 中等性能
location /static/ {
## 静态资源目录
}
## 正则匹配 - 最低性能(需要时使用)
location ~* \.(js|css|png)$ {
## 文件类型匹配
}匹配优先级顺序
- 精确匹配 (
location =) - 立即返回 - 前缀匹配 (
location /path/) - 最长前缀优先 - 正则匹配 (
location ~) - 顺序匹配
最佳实践
- 高频访问路径使用精确匹配
- 开启 PCRE JIT 提升正则性能
- 按性能需求合理安排匹配顺序
下载速度限制优化
通过连接限制和速率控制,防止单个用户占用过多带宽,保障服务稳定性。
连接限制区域定义
## 定义连接限制区域(基于客户端IP)
limit_conn_zone $binary_remote_addr zone=conn_for_remote_addr:1m; ## 1MB可存储约8000个IP下载速度限制配置
location /videos/ {
## 连接数限制:每个IP最多10个并发连接
limit_conn conn_for_remote_addr 10; ## 并发控制
## 速率限制:前1MB全速,之后限速250KB/s
limit_rate_after 1m; ## 初始全速
limit_rate 250k; ## 后续限速
## 可选:限制缓冲区大小
limit_rate_after 0; ## 立即限速模式
}多级速率限制
## 大文件下载:阶梯式限速
location /large-files/ {
limit_conn conn_for_remote_addr 5;
limit_rate_after 10m; ## 前10MB全速
limit_rate 1m; ## 之后限速1MB/s
## 超大数据进一步限速
if ($content_length > 100m) {
limit_rate_after 50m;
limit_rate 500k;
}
}用户类型差异化限制
## 基于用户身份的限速
map $http_cookie $user_tier {
default "free";
"~*premium=true" "premium";
"~*vip=true" "vip";
}
location /download/ {
limit_conn conn_for_remote_addr 8;
## 免费用户严格限制
if ($user_tier = "free") {
limit_rate_after 5m;
limit_rate 100k;
}
## 付费用户较宽松
if ($user_tier = "premium") {
limit_rate_after 50m;
limit_rate 1m;
}
## VIP用户基本不限速
if ($user_tier = "vip") {
limit_rate_after 500m;
limit_rate 10m;
}
}文件类型差异化限制
## 视频流媒体特殊处理
location ~* \.(mp4|avi|mkv)$ {
limit_conn conn_for_remote_addr 3; ## 视频连接数限制更严格
limit_rate_after 2m; ## 缓冲2MB后开始限速
limit_rate 500k; ## 保证流畅播放的速率
}
## 普通文件下载
location ~* \.(zip|rar|exe)$ {
limit_conn conn_for_remote_addr 2;
limit_rate_after 0; ## 立即开始限速
limit_rate 200k;
}