【Nginx 】网站优化深度指南

66 阅读11分钟

前言

Jym好😘,我是珑墨,今天给大家分享  【Nginx 】网站优化深度指南 ,嘎嘎的😍,看下面。

Nginx可以说是Web架构的核心服务,其配置优化直接影响网站的性能、安全性和用户体验。下面咱将从基础配置到前沿技术,全面介绍 Nginx 网站优化的实战方法,涵盖性能调优、安全加固、高可用部署等关键领域。


性能优化核心配置

1. Worker 进程优化

Nginx 采用多进程模型,合理配置 worker 进程数量是性能优化的基础。

# /etc/nginx/nginx.conf

# 主配置段
user nginx;
worker_processes auto;  # 自动检测 CPU 核心数
worker_cpu_affinity auto;  # CPU 亲和性绑定(Linux)

# 连接处理优化
worker_rlimit_nofile 65535;  # 每个 worker 最大文件描述符数

events {
    use epoll;  # Linux 下使用 epoll 事件模型
    worker_connections 8192;  # 每个 worker 最大连接数
    multi_accept on;  # 一次 accept 多个连接
    accept_mutex off;  # 现代内核下关闭 accept 互斥锁
}

优化说明:

  • worker_processes auto:自动根据 CPU 核心数设置,避免过度配置
  • worker_rlimit_nofile:提高文件描述符限制,支持更多并发连接
  • use epoll:Linux 下高性能事件模型
  • multi_accept on:减少系统调用次数,提升效率

2. 缓冲区优化

合理设置缓冲区大小,减少 I/O 操作,提升响应速度。

http {
    # 基础缓冲区设置
    client_body_buffer_size 128k;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 16k;
    
    # 响应缓冲区
    output_buffers 1 32k;
    postpone_output 1460;
    
    # 发送文件优化
    sendfile on;
    sendfile_max_chunk 512k;
    tcp_nopush on;
    tcp_nodelay on;
    
    # 超时设置
    keepalive_timeout 65;
    keepalive_requests 100;
    client_body_timeout 12;
    client_header_timeout 12;
    send_timeout 10;
}

关键参数解析:

  • sendfile on:使用内核级别的零拷贝技术,提升文件传输效率
  • tcp_nopushtcp_nodelay:配合使用,优化 TCP 传输
  • keepalive_requests:单个连接最大请求数,减少连接开销

3. Gzip 压缩优化

启用 Gzip 压缩,显著减少传输数据量。

http {
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_min_length 1000;
    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";
    
    # Brotli 压缩(需要编译支持)
    # 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;
}

压缩策略:

  • 压缩级别 6:平衡压缩比与 CPU 消耗
  • 最小长度 1000:避免小文件压缩开销
  • 包含字体和 SVG:现代 Web 应用常见资源

缓存策略优化

1. 浏览器缓存配置

通过 HTTP 缓存头控制浏览器缓存行为。

server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }
    
    # HTML 文件短期缓存或禁用缓存
    location ~* \.(html|htm)$ {
        expires 1h;
        add_header Cache-Control "public, must-revalidate";
    }
    
    # API 接口禁用缓存
    location /api/ {
        add_header Cache-Control "no-cache, no-store, must-revalidate";
        add_header Pragma "no-cache";
        add_header Expires "0";
    }
}

2. Nginx 代理缓存

配置反向代理缓存,减少后端服务器压力。

http {
    # 定义缓存路径和参数
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g 
                     inactive=60m use_temp_path=off;
    
    # 缓存键设置
    proxy_cache_key "$scheme$request_method$host$request_uri";
    
    upstream backend {
        server 192.168.1.10:8080;
        server 192.168.1.11:8080;
    }
    
    server {
        listen 80;
        server_name example.com;
        
        location / {
            proxy_pass http://backend;
            
            # 缓存配置
            proxy_cache my_cache;
            proxy_cache_valid 200 302 10m;
            proxy_cache_valid 404 1m;
            proxy_cache_valid any 5m;
            
            # 缓存状态头(调试用)
            add_header X-Cache-Status $upstream_cache_status;
            
            # 缓存控制
            proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
            proxy_cache_background_update on;
            proxy_cache_revalidate on;
            proxy_cache_lock on;
            
            # 代理头
            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_set_header X-Forwarded-Proto $scheme;
        }
        
        # 缓存清理接口(需要 ngx_cache_purge 模块)
        # 安装方法:https://github.com/nginx-modules/ngx_cache_purge
        location ~ /purge(/.*) {
            allow 127.0.0.1;
            allow 192.168.1.0/24;
            deny all;
            proxy_cache_purge my_cache $scheme$request_method$host$1;
        }
    }
}

缓存策略要点:

  • keys_zone:定义缓存内存区域,10m 可存储约 8 万键
  • max_size:磁盘缓存最大容量
  • inactive:未访问缓存过期时间
  • proxy_cache_use_stale:后端故障时使用过期缓存

3. FastCGI 缓存

PHP 等动态内容缓存配置。

http {
    # FastCGI 缓存路径必须在 http 块中定义(不能在 server 块)
    fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fcgi_cache:10m max_size=10g 
                       inactive=60m;
    
    server {
        location ~ \.php$ {
            fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
            
            # FastCGI 缓存
            fastcgi_cache fcgi_cache;
            fastcgi_cache_valid 200 60m;
            fastcgi_cache_bypass $http_pragma $http_authorization;
            fastcgi_no_cache $http_pragma $http_authorization;
            
            # 缓存键包含用户标识(如需要个性化)
            fastcgi_cache_key "$scheme$request_method$host$request_uri$cookie_user";
            
            add_header X-FastCGI-Cache $upstream_cache_status;
        }
    }
}

注意:

  • fastcgi_cache_path 必须在 http 块中定义,不能在 server 块中
  • 确保缓存目录存在且有写权限:mkdir -p /var/cache/nginx/fastcgi && chown nginx:nginx /var/cache/nginx/fastcgi

连接与并发优化

1. 连接池优化

http {
    # 上游连接池
    upstream backend {
        server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
        server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
        
        # 连接保持
        keepalive 32;
        keepalive_requests 100;
        keepalive_timeout 60s;
    }
    
    server {
        location / {
            proxy_pass http://backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            
            # 连接复用
            proxy_connect_timeout 5s;
            proxy_send_timeout 10s;
            proxy_read_timeout 10s;
        }
    }
}

2. 限流与防刷

http {
    # 限流区域定义
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=general_limit:10m rate=50r/s;
    
    # 连接数限制
    limit_conn_zone $binary_remote_addr zone=addr_limit:10m;
    
    server {
        # API 接口限流
        location /api/ {
            limit_req zone=api_limit burst=20 nodelay;
            limit_conn addr_limit 10;
            limit_req_status 429;
            limit_conn_status 429;
            
            proxy_pass http://backend;
        }
        
        # 通用限流
        location / {
            limit_req zone=general_limit burst=50 nodelay;
            limit_conn addr_limit 20;
        }
    }
}

限流策略说明:

  • rate=10r/s:平均每秒 10 个请求
  • burst=20:允许突发 20 个请求
  • nodelay:立即处理突发请求,不排队

HTTP/2 与 HTTP/3 部署

1. HTTP/2 配置

server {
    listen 443 ssl http2;
    server_name example.com;
    
    # SSL/TLS 配置
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    
    # 现代 TLS 配置
    ssl_protocols TLSv1.2 TLSv1.3;
    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 off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_session_tickets off;
    
    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/nginx/ssl/chain.crt;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    
    # HSTS
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    
    # HTTP/2 推送(如需要)
    # http2_push /style.css;
    # http2_push /app.js;
}

2. HTTP/3 (QUIC) 配置

Nginx 1.25.0+ 支持 HTTP/3,需要编译时启用。

server {
    # HTTP/3 监听(UDP 443)
    listen 443 http3 reuseport;
    # HTTP/2 和 HTTP/1.1 回退(TCP 443)
    listen 443 ssl http2;
    
    server_name example.com;
    
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    
    # HTTP/3 需要 TLS 1.3
    ssl_protocols TLSv1.3;
    
    # Alt-Svc 头(告知客户端支持 HTTP/3)
    # 注意:HTTP/3 使用 UDP,需要确保防火墙允许 UDP 443
    add_header Alt-Svc 'h3=":443"; ma=86400' always;
    
    # 其他配置...
    location / {
        root /var/www/html;
    }
}

编译 Nginx 支持 HTTP/3:

选项 1:使用 BoringSSL(推荐用于 HTTP/3)

# 下载 BoringSSL
git clone https://github.com/google/boringssl.git
cd boringssl
mkdir build && cd build
cmake .. && make

# 编译 Nginx
./configure \
    --with-http_v3_module \
    --with-http_ssl_module \
    --with-openssl=../boringssl \
    --with-cc-opt="-I../boringssl/include" \
    --with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto"
make && sudo make install

选项 2:使用 OpenSSL 3.x(更常见)

# 使用系统 OpenSSL 3.x(需要 OpenSSL 1.1.1+)
./configure \
    --with-http_v3_module \
    --with-http_ssl_module
make && sudo make install

注意:

  • HTTP/3 需要 Nginx 1.25.0+ 版本
  • BoringSSL 提供更好的 HTTP/3 支持,但 OpenSSL 3.x 也可用
  • 确保防火墙允许 UDP 443 端口(QUIC 使用 UDP)
  • 编译前确保已安装必要的开发库:apt-get install build-essential libpcre3-dev zlib1g-dev(Debian/Ubuntu)

安全优化实践

1. 安全响应头

server {
    # 隐藏 Nginx 版本
    server_tokens off;
    
    # 安全响应头
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
}

2. 请求过滤与防护

http {
    # 禁用危险方法
    if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$ ) {
        return 405;
    }
    
    # 阻止常见攻击模式
    location ~* \.(php|jsp|cgi|asp|aspx)$ {
        deny all;
        return 403;
    }
    
    # SQL 注入和 XSS 防护(基础)
    set $block 0;
    if ($query_string ~* "union.*select.*\(|union.*all.*select.*\(|concat.*\(|\.\.\/|\.\.\\|exec.*\(|script.*<|javascript:|onerror=|onload=|<iframe") {
        set $block 1;
    }
    if ($block = 1) {
        return 403;
    }
    
    # 限制请求体大小
    client_max_body_size 10m;
    
    # 隐藏服务器信息(需要 headers-more-nginx-module 模块)
    # 安装方法:https://github.com/openresty/headers-more-nginx-module
    # more_set_headers -s 400,403,404,500,502,503,504 "Server: nginx";
    
    # 或者使用标准方法隐藏版本(已在 server 块中配置 server_tokens off)
}

3. IP 白名单与黑名单

geo $blocked_ip {
    default 0;
    # 黑名单 IP
    192.168.1.100 1;
    10.0.0.50 1;
    # 从文件读取
    include /etc/nginx/blocked_ips.conf;
}

server {
    if ($blocked_ip) {
        return 403;
    }
    
    # 管理后台 IP 白名单
    location /admin/ {
        allow 192.168.1.0/24;
        allow 10.0.0.0/8;
        deny all;
        
        proxy_pass http://backend;
    }
}

负载均衡与高可用

1. 负载均衡策略

upstream backend {
    # 轮询(默认)
    # server 192.168.1.10:8080;
    # server 192.168.1.11:8080;
    
    # 权重轮询
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=1;
    
    # IP 哈希(会话保持)
    # ip_hash;
    
    # 最少连接
    # least_conn;
    
    # 一致性哈希(需要第三方模块)
    # hash $request_uri consistent;
    
    # 健康检查
    server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 max_fails=3 fail_timeout=30s backup;
    
    # 连接保持
    keepalive 32;
}

server {
    location / {
        proxy_pass http://backend;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_next_upstream_tries 3;
        proxy_next_upstream_timeout 10s;
    }
}

2. 主备与故障转移

upstream backend {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080 backup;  # 备用服务器
    server 192.168.1.12:8080 down;    # 临时下线
}

# 使用 Nginx Plus 健康检查
upstream backend {
    zone backend 64k;
    least_conn;
    
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    
    # 主动健康检查
    health_check interval=5s fails=3 passes=2 uri=/health;
}

日志与监控优化

1. 日志格式优化

http {
    # 自定义日志格式
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" '
                    'rt=$request_time uct="$upstream_connect_time" '
                    'uht="$upstream_header_time" urt="$upstream_response_time"';
    
    log_format json escape=json
        '{'
            '"time_local":"$time_local",'
            '"remote_addr":"$remote_addr",'
            '"remote_user":"$remote_user",'
            '"request":"$request",'
            '"status": $status,'
            '"body_bytes_sent":$body_bytes_sent,'
            '"request_time":$request_time,'
            '"http_referrer":"$http_referer",'
            '"http_user_agent":"$http_user_agent"'
        '}';
    
    access_log /var/log/nginx/access.log main buffer=32k flush=5s;
    error_log /var/log/nginx/error.log warn;
    
    # 按域名分离日志
    server {
        server_name example.com;
        access_log /var/log/nginx/example.com.access.log main;
    }
}

2. 性能监控配置

# 启用状态监控(需要 stub_status 模块)
server {
    listen 127.0.0.1:8080;
    server_name localhost;
    
    location /nginx_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

# 输出示例:
# Active connections: 291
# server accepts handled requests
#  16630948 16630948 31070465
# Reading: 6 Writing: 179 Waiting: 106

3. 实时日志分析

使用 GoAccess 或 ELK 进行日志分析:

# GoAccess 实时分析
goaccess /var/log/nginx/access.log --log-format=COMBINED --real-time-html --output=/var/www/report.html

# 或使用 tail + awk 简单统计
tail -f /var/log/nginx/access.log | awk '{print $9}' | sort | uniq -c | sort -rn

前沿技术应用

1. 动态模块加载

Nginx 1.9.11+ 支持动态模块,无需重新编译。

# 加载动态模块
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
load_module modules/ngx_http_geoip2_module.so;

2. 流媒体与 WebSocket

# RTMP 流媒体(需要 nginx-rtmp-module)
rtmp {
    server {
        listen 1935;
        application live {
            live on;
            record off;
            hls on;
            hls_path /var/www/hls;
            hls_fragment 3s;
            hls_playlist_length 60s;
        }
    }
}

# WebSocket 代理
server {
    location /ws/ {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 86400;
    }
}

3. 边缘计算与 CDN 集成

# 边缘缓存配置
http {
    map $http_cf_visitor $is_bot {
        default 0;
        ~*bot 1;
    }
    
    server {
        # Cloudflare 或 CDN 集成
        set_real_ip_from 173.245.48.0/20;
        set_real_ip_from 103.21.244.0/22;
        real_ip_header CF-Connecting-IP;
        
        # 区分爬虫和真实用户
        if ($is_bot) {
            return 403;
        }
    }
}

4. 微服务与 API 网关

# API 网关配置
upstream user_service {
    server 192.168.1.20:8001;
}

upstream order_service {
    server 192.168.1.21:8002;
}

server {
    location /api/users/ {
        rewrite ^/api/users/(.*) /$1 break;
        proxy_pass http://user_service;
    }
    
    location /api/orders/ {
        rewrite ^/api/orders/(.*) /$1 break;
        proxy_pass http://order_service;
    }
    
    # API 版本控制
    location ~ ^/api/v(\d+)/(.*)$ {
        set $version $1;
        set $path $2;
        rewrite ^ /v$version/$path break;
        proxy_pass http://backend;
    }
}

实战例与性能测试

例 1:高并发电商网站优化

场景: 日 PV 1000 万,峰值 QPS 5000

优化配置:

# nginx.conf
user nginx;
worker_processes auto;
worker_rlimit_nofile 100000;

events {
    use epoll;
    worker_connections 16384;
    multi_accept on;
}

http {
    # 基础优化
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 30;
    keepalive_requests 1000;
    
    # 压缩
    gzip on;
    gzip_vary on;
    gzip_comp_level 6;
    gzip_min_length 1000;
    gzip_types text/plain text/css application/json application/javascript text/xml;
    
    # 缓存
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=product_cache:100m 
                     max_size=50g inactive=24h use_temp_path=off;
    
    # 限流
    limit_req_zone $binary_remote_addr zone=product_limit:10m rate=20r/s;
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
    
    upstream backend {
        least_conn;
        server 10.0.1.10:8080 max_fails=3 fail_timeout=10s;
        server 10.0.1.11:8080 max_fails=3 fail_timeout=10s;
        keepalive 64;
    }
    
    server {
        listen 80;
        server_name shop.example.com;
        
        # 静态资源
        location ~* \.(jpg|jpeg|png|gif|css|js|woff|woff2)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
            access_log off;
        }
        
        # 商品详情页缓存
        location ~ ^/product/(\d+)$ {
            limit_req zone=product_limit burst=30 nodelay;
            
            proxy_pass http://backend;
            proxy_cache product_cache;
            proxy_cache_valid 200 10m;
            proxy_cache_key "$scheme$request_method$host$request_uri";
            add_header X-Cache-Status $upstream_cache_status;
        }
        
        # API 接口
        location /api/ {
            limit_req zone=product_limit burst=10 nodelay;
            limit_conn conn_limit 5;
            
            proxy_pass http://backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
        }
    }
}

性能测试结果:

# 使用 wrk 压测
wrk -t12 -c400 -d30s --timeout 10s https://shop.example.com/product/12345

# 优化前:QPS 2000,平均响应时间 200ms
# 优化后:QPS 8000,平均响应时间 50ms

例 2:API 服务优化

场景: RESTful API,需要低延迟高并发

http {
    # 连接池
    upstream api_backend {
        least_conn;
        server 192.168.1.30:3000;
        server 192.168.1.31:3000;
        keepalive 100;
    }
    
    # API 限流
    limit_req_zone $binary_remote_addr zone=api_rate:10m rate=100r/s;
    limit_req_zone $binary_remote_addr zone=api_strict:10m rate=10r/s;
    
    server {
        listen 443 ssl http2;
        server_name api.example.com;
        
        # 禁用缓存
        add_header Cache-Control "no-store, no-cache, must-revalidate";
        
        location /api/v1/ {
            # 限流
            limit_req zone=api_rate burst=200 nodelay;
            
            # CORS
            add_header Access-Control-Allow-Origin * always;
            add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
            add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
            
            if ($request_method = OPTIONS) {
                return 204;
            }
            
            # 代理
            proxy_pass http://api_backend;
            proxy_http_version 1.1;
            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 3s;
            proxy_send_timeout 5s;
            proxy_read_timeout 5s;
        }
        
        # 敏感接口更严格限流
        location /api/v1/payment/ {
            limit_req zone=api_strict burst=5 nodelay;
            proxy_pass http://api_backend;
        }
    }
}

例 3:WordPress 多站点优化

# WordPress 优化配置
# 注意:fastcgi_cache_path 必须在 http 块中定义,不能在 server 块中

http {
    # FastCGI 缓存路径(必须在 http 块)
    fastcgi_cache_path /var/cache/nginx/wordpress levels=1:2 
                       keys_zone=wp_cache:50m max_size=5g inactive=60m;
    
    server {
        listen 80;
        server_name blog.example.com;
        root /var/www/wordpress;
        index index.php;
        
        location / {
            try_files $uri $uri/ /index.php?$args;
        }
        
        location ~ \.php$ {
            fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
            
            # 缓存
            fastcgi_cache wp_cache;
            fastcgi_cache_valid 200 60m;
            fastcgi_cache_bypass $http_pragma $http_authorization $cookie_comment_author;
            fastcgi_no_cache $http_pragma $http_authorization $cookie_comment_author;
            
            add_header X-FastCGI-Cache $upstream_cache_status;
        }
        
        # 静态资源
        location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
            access_log off;
        }
        
        # 禁止访问敏感文件
        location ~ /\. {
            deny all;
            access_log off;
            log_not_found off;
        }
        
        # WordPress 安全配置
        location ~ /wp-admin {
            # 限制访问频率
            limit_req zone=general_limit burst=10 nodelay;
        }
        
        # 禁止执行 PHP 文件上传目录
        location ~* /wp-content/uploads/.*\.php$ {
            deny all;
        }
    }
}

系统级优化配置

1. 系统文件描述符限制

Nginx 需要足够的文件描述符来处理高并发连接。

# 编辑 /etc/security/limits.conf
# 添加以下内容
* soft nofile 65535
* hard nofile 65535
nginx soft nofile 65535
nginx hard nofile 65535

# 编辑 /etc/systemd/system/nginx.service.d/override.conf(如果使用 systemd)
[Service]
LimitNOFILE=65535

# 重新加载配置
systemctl daemon-reload
systemctl restart nginx

2. 内核参数优化(sysctl)

# 编辑 /etc/sysctl.conf,添加以下配置

# TCP 连接优化
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535

# TCP 连接复用
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30

# TCP 缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# TCP 连接追踪
net.netfilter.nf_conntrack_max = 262144

# 应用配置
sysctl -p

3. 日志轮转配置

使用 logrotate 管理日志文件,避免日志文件过大。

# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 0640 nginx adm
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

配置测试与验证

1. 配置文件测试

在应用配置前,务必先测试配置文件语法。

# 测试配置文件语法
nginx -t

# 测试配置文件并显示所有配置
nginx -T

# 测试配置文件并显示版本信息
nginx -V

# 如果测试通过,重新加载配置(不中断服务)
nginx -s reload

# 或者使用 systemd
systemctl reload nginx

2. 性能验证

# 检查 Nginx 状态
systemctl status nginx

# 查看 Nginx 进程
ps aux | grep nginx

# 查看连接数
netstat -an | grep :80 | wc -l
# 或使用 ss(更现代)
ss -ant | grep :80 | wc -l

# 查看 Nginx 统计信息(如果配置了 stub_status)
curl http://127.0.0.1:8080/nginx_status

3. 错误排查

# 查看错误日志
tail -f /var/log/nginx/error.log

# 查看访问日志
tail -f /var/log/nginx/access.log

# 检查配置文件包含的路径
nginx -T 2>&1 | grep -E "include|conf"

# 查看 Nginx 版本和编译信息
nginx -V

错误页面自定义

提供友好的错误页面,提升用户体验。

http {
    # 自定义错误页面
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    
    server {
        # 404 错误页面
        location = /404.html {
            root /var/www/html;
            internal;
        }
        
        # 50x 错误页面
        location = /50x.html {
            root /var/www/html;
            internal;
        }
        
        # 或者使用自定义错误页面并返回 JSON(API 服务)
        location /api/ {
            error_page 404 = @api_not_found;
            error_page 500 502 503 504 = @api_error;
            
            proxy_pass http://backend;
        }
        
        location @api_not_found {
            default_type application/json;
            return 404 '{"error":"Not Found","code":404}';
        }
        
        location @api_error {
            default_type application/json;
            return 500 '{"error":"Internal Server Error","code":500}';
        }
    }
}

SSL 证书自动续期

使用 Let's Encrypt 和 Certbot 实现证书自动续期。

# 安装 Certbot
apt-get install certbot python3-certbot-nginx  # Debian/Ubuntu
yum install certbot python3-certbot-nginx      # CentOS/RHEL

# 申请证书
certbot --nginx -d example.com -d www.example.com

# 测试自动续期
certbot renew --dry-run

# 设置自动续期(添加到 crontab)
crontab -e
# 添加以下行(每月检查并续期)
0 0 1 * * certbot renew --quiet --deploy-hook "systemctl reload nginx"

Nginx 配置示例(自动续期):

server {
    listen 80;
    server_name example.com www.example.com;
    
    # Let's Encrypt 验证路径
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }
    
    # HTTP 重定向到 HTTPS
    location / {
        return 301 https://$server_name$request_uri;
    }
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    
    # SSL 证书(Certbot 会自动配置)
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # 其他配置...
}

性能测试与调优建议

1. 压力测试工具

# Apache Bench (ab)
ab -n 10000 -c 100 https://example.com/

# wrk(更现代)
wrk -t4 -c100 -d30s --timeout 10s https://example.com/

# 使用 Vegeta
echo "GET https://example.com/" | vegeta attack -duration=30s -rate=1000 | vegeta report

2. 性能监控指标

  • QPS(每秒请求数):衡量吞吐量
  • 响应时间:P50、P95、P99 延迟
  • 错误率:4xx、5xx 错误比例
  • 连接数:活跃连接和等待连接
  • 缓存命中率$upstream_cache_status 统计

3. 调优检查清单

基础配置:

  • Worker 进程数 = CPU 核心数
  • 文件描述符限制 ≥ 65535(系统级和 Nginx 配置)
  • 启用 sendfile 和 tcp_nopush
  • 配置合理的 keepalive 超时
  • 配置系统内核参数(sysctl)

性能优化:

  • 启用 Gzip/Brotli 压缩
  • 配置静态资源缓存
  • 设置代理缓存(如适用)
  • 配置 FastCGI 缓存(如适用)
  • 优化缓冲区大小

安全与限流:

  • 配置限流防止过载
  • 配置安全响应头
  • 隐藏服务器版本信息
  • 配置 IP 白名单/黑名单
  • 设置 SSL/TLS 最佳实践

协议与模块:

  • 启用 HTTP/2 或 HTTP/3
  • 配置 OCSP Stapling
  • 启用 HSTS
  • 安装必要的第三方模块

监控与维护:

  • 优化日志格式和轮转
  • 配置日志轮转(logrotate)
  • 设置性能监控(stub_status 或 Prometheus)
  • 配置错误页面
  • 设置 SSL 证书自动续期
  • 定期进行性能测试

部署验证:

  • 配置文件语法测试通过(nginx -t)
  • 性能测试通过(QPS、延迟满足要求)
  • 监控指标正常(错误率、缓存命中率等)
  • 安全测试通过(SSL Labs、安全响应头检查)

常见问题与解决方案

1. 502 Bad Gateway

原因: 后端服务器无响应或连接超时

解决方案:

# 增加超时时间
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# 检查后端服务状态
# 查看 FastCGI 进程
ps aux | grep php-fpm
# 检查 PHP-FPM 配置
systemctl status php8.1-fpm

2. 413 Request Entity Too Large

原因: 上传文件超过限制

解决方案:

# 增加客户端请求体大小限制
client_max_body_size 50m;

# 同时检查 PHP 配置
# php.ini: upload_max_filesize = 50M
# php.ini: post_max_size = 50M

3. 缓存不生效

排查步骤:

# 检查缓存目录权限
ls -la /var/cache/nginx/
chown -R nginx:nginx /var/cache/nginx/

# 检查缓存状态头
curl -I http://example.com/ | grep X-Cache-Status

# 查看缓存键
# 在配置中添加缓存调试
add_header X-Cache-Key "$scheme$request_method$host$request_uri";

4. 高并发下连接数不足

解决方案:

# 1. 检查系统限制
ulimit -n

# 2. 增加系统文件描述符限制(见系统级优化配置)

# 3. 调整 Nginx 配置
worker_rlimit_nofile 100000;
worker_connections 16384;

# 4. 优化内核参数
net.core.somaxconn = 65535

5. SSL 证书问题

# 检查证书有效期
openssl x509 -in /etc/nginx/ssl/cert.pem -noout -dates

# 测试 SSL 配置
openssl s_client -connect example.com:443 -servername example.com

# 在线测试工具
# https://www.ssllabs.com/ssltest/

总结

Nginx 优化是一个系统工程,需要根据实际业务场景进行针对性配置。关键优化点包括:

  1. 性能优化:Worker 进程、连接处理、缓冲区、压缩、系统级参数
  2. 缓存策略:浏览器缓存、代理缓存、FastCGI 缓存
  3. 安全加固:安全响应头、请求过滤、IP 限制、SSL/TLS 配置
  4. 负载均衡:多种算法选择、健康检查、故障转移
  5. 前沿技术:HTTP/2/3、动态模块、边缘计算
  6. 运维管理:配置测试、日志轮转、监控告警、证书管理

最佳实践建议:

  1. 配置前先测试:使用 nginx -t 验证配置语法
  2. 渐进式优化:一次修改一个参数,观察效果后再继续
  3. 持续监控:建立监控体系,及时发现问题
  4. 定期审查:定期检查配置,清理无用规则
  5. 文档化:记录配置变更和优化效果
  6. 备份配置:修改前备份原配置,便于回滚

持续监控和调优是保持高性能的关键。建议定期进行压力测试,根据实际负载调整配置参数,并关注 Nginx 官方更新和新特性,以上这些已经够工作中常用且非常全面了。


参考资料