Nginx 架构

Nginx 采用 master-worker 多进程模型:

              Master Process (root)
              │  读取配置、管理 worker
    ┌─────────┼─────────┐
    │         │         │
 Worker 1  Worker 2  Worker N
 (nginx)   (nginx)   (nginx)
    │         │         │
  epoll     epoll     epoll
    │         │         │
 事件循环    事件循环   事件循环

每个 worker 是一个独立进程,处理所有连接。worker 数量建议等于 CPU 核心数。

Worker 进程配置

# /etc/nginx/nginx.conf

# 自动设置为 CPU 核心数
worker_processes auto;

# 绑定到特定 CPU(可选)
worker_cpu_affinity auto;

# 每个 worker 的最大打开文件数
worker_rlimit_nofile 65535;

# 错误日志级别
error_log /var/log/nginx/error.log warn;

events {
    # 每个 worker 的最大连接数
    worker_connections 10240;

    # 使用 epoll 事件模型(Linux)
    use epoll;

    # 一次接受多个新连接
    multi_accept on;

    # 通知工作线程接受连接
    accept_mutex off;
}

负载均衡配置

upstream 配置

upstream backend {
    # 负载均衡算法
    # least_conn;          # 最少连接
    # ip_hash;             # IP 哈希
    # hash $request_uri;   # URI 哈希
    # round-robin;         # 轮询(默认)

    server 10.0.0.1:8080 weight=3 max_fails=3 fail_timeout=30s;
    server 10.0.0.2:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 10.0.0.3:8080 backup;

    # 长连接池
    keepalive 32;
    keepalive_timeout 60s;
    keepalive_requests 1000;
}

server {
    listen 80;

    location / {
        proxy_pass http://backend;

        # HTTP 头设置
        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;

        # 超时设置
        proxy_connect_timeout 5s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;

        # 缓冲区设置
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 16k;
        proxy_busy_buffers_size 32k;

        # HTTP 版本
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

keepalive 的重要性

默认 Nginx 每次请求都会与上游建立新连接。启用 keepalive 后,可以复用连接:

# 查看到上游的连接状态
ss -tnp | grep :8080

# 启用 keepalive 前: 每次请求都有 TIME_WAIT
# 启用 keepalive 后: 连接复用,连接数大幅减少

缓冲区与缓存

代理缓冲区

location / {
    proxy_pass http://backend;

    # 启用缓冲(默认开启)
    proxy_buffering on;

    # 响应头缓冲区(存 headers)
    proxy_buffer_size 4k;

    # 响应体缓冲区(存 body)
    proxy_buffers 8 16k;
    proxy_busy_buffers_size 32k;

    # 临时文件
    proxy_temp_file_write_size 64k;
    proxy_temp_path /var/cache/nginx/proxy_temp 1 2;
}

缓存配置

# 定义缓存路径
proxy_cache_path /var/cache/nginx/proxy
    levels=1:2
    keys_zone=MY_CACHE:10m
    max_size=1g
    inactive=60m
    use_temp_path=off;

server {
    location / {
        proxy_cache MY_CACHE;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_key $scheme$proxy_host$request_uri;

        # 缓存状态
        add_header X-Cache-Status $upstream_cache_status;

        proxy_pass http://backend;
    }
}

查看缓存命中率:

# X-Cache-Status 头: HIT, MISS, EXPIRED, STALE 等
curl -I http://example.com/ | grep X-Cache

限速配置

限制请求速率

# 定义限速区域
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;

server {
    # API 限速
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        proxy_pass http://backend;
    }

    # 登录接口严格限速
    location /api/login {
        limit_req zone=login burst=5 nodelay;
        proxy_pass http://backend;
    }

    # 自定义限速返回码
    limit_req_status 429;
}

限制并发连接

limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    location /download/ {
        limit_conn addr 5;       # 每 IP 最多 5 个并发连接
        limit_rate 500k;         # 每连接限速 500KB/s
        limit_rate_after 10m;    # 前 10MB 不限速
    }
}

性能调优总结

# 完整的性能优化配置
worker_processes auto;
worker_rlimit_nofile 65535;

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

http {
    # 基础优化
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    keepalive_requests 1000;

    # 缓冲区
    client_body_buffer_size 16k;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;
    client_max_body_size 100m;

    # Gzip
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_types text/plain text/css application/json application/javascript
               text/xml application/xml application/xml+rss text/javascript
               image/svg+xml;

    # 日志优化
    access_log off;
    # 或使用缓冲写入
    # access_log /var/log/nginx/access.log main buffer=32k flush=5s;
}

监控与诊断

# 查看 Nginx 工作进程
ps aux | grep nginx

# 查看连接数
ss -ant | grep :80 | wc -l

# 查看 worker 连接使用情况
# 需要启用 stub_status 模块
curl http://localhost/nginx_status

# 实时监控
watch -n1 'curl -s http://localhost/nginx_status'

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

总结

Nginx 的性能调优是一个系统工程,需要从 worker 配置、连接管理、缓冲区、限速等多个维度综合考虑。关键是理解每个参数的含义,根据实际负载进行调整。