Nginx 高并发配置与性能优化实战

网络协议

Nginx 高并发:从架构到实战

Nginx 凭借事件驱动、非阻塞 I/O 架构,单机即可支撑数万并发连接。但默认配置远未发挥其潜力,需要针对业务场景深度调优。

优化维度 关键参数 影响范围
进程模型 worker_processes, worker_connections 并发承载能力
事件模型 use epoll, multi_accept 事件处理效率
负载均衡 upstream, proxy_next_upstream 流量分发与容错
缓冲与超时 proxy_buffers, keepalive_timeout 内存与连接复用
压缩 gzip, gzip_comp_level 传输带宽
安全 limit_req, limit_conn 流量防护

一、Nginx 架构:事件驱动与 Worker 进程

Master-Worker 模型

Nginx 采用 Master-Worker 多进程架构:

  • Master 进程:读取配置、绑定端口、管理 Worker(fork/信号/重启)
  • Worker 进程:独立处理请求,互不干扰,一个 Worker 崩溃不影响其他
# 查看 Nginx 进程结构
# ps aux | grep nginx
# root      1234  nginx: master process
# www-data  1235  nginx: worker process
# www-data  1236  nginx: worker process

事件驱动模型

Nginx 基于 Reactor 模式,使用 I/O 多路复用技术:

I/O 模型 平台 性能
epoll Linux 最优,O(1) 事件通知
kqueue FreeBSD/macOS 优秀,类似 epoll
select 通用 较差,fd_set 上限 1024
poll 通用 一般,无上限但线性扫描
events {
    use epoll;
    worker_connections 65535;
    multi_accept on;
    accept_mutex off;
}

multi_accept on 让 Worker 一次接受所有新连接,减少系统调用次数。accept_mutex off 在高并发下避免惊群效应(Linux 3.9+ 内核已支持 SO_REUSEPORT)。


二、核心并发配置

worker_processes

# 自动检测 CPU 核心数(推荐)
worker_processes auto;

# 或手动指定(通常等于 CPU 核心数或其 2 倍)
worker_processes 8;

调优建议

  • 一般设为 auto,与 CPU 核心数一致
  • CPU 密集型场景(SSL、gzip)可设为核心数
  • I/O 密集型场景可适当增至 2 倍核心数

worker_connections

events {
    worker_connections 65535;
}

最大并发连接数 = worker_processes × worker_connections。需同步调整系统文件描述符限制:

# 临时修改
ulimit -n 65535

# 永久修改(/etc/security/limits.conf)
* soft nofile 65535
* hard nofile 65535

worker_rlimit_nofile

# Worker 进程最大文件描述符数
worker_rlimit_nofile 65535;

完整基础配置

user www-data;
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    use epoll;
    worker_connections 65535;
    multi_accept on;
    accept_mutex off;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile      on;
    tcp_nopush    on;
    tcp_nodelay   on;
    keepalive_timeout 65;
    keepalive_requests 100;

    # ... 其他配置
}

三、负载均衡算法详解

基本配置

upstream backend {
    server 10.0.0.1:8080 weight=5;
    server 10.0.0.2:8080 weight=3;
    server 10.0.0.3:8080 weight=2;
    server 10.0.0.4:8080 backup;
}

五种调度算法对比

算法 指令 特点 适用场景
轮询 (默认) 依次分配,均匀 后端性能一致
加权轮询 weight=N 按权重比例分配 后端性能差异
最少连接 least_conn 优先分配给连接数最少的服务器 长连接/请求耗时差异大
IP 哈希 ip_hash 同一 IP 固定分配到同一服务器 需要会话保持
随机 random 随机选择 无状态服务
一致性哈希 hash $key consistent 一致性哈希环 缓存服务器

least_conn 配置

upstream api_backend {
    least_conn;
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}

ip_hash 配置

upstream web_backend {
    ip_hash;
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}

注意ip_hash 不支持 backupweight。生产环境建议使用一致性哈希替代。

一致性哈希配置

upstream cache_backend {
    hash $request_uri consistent;
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}

四、Upstream 健康检查

被动健康检查(内置)

upstream backend {
    server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;
    server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;
    server 10.0.0.3:8080 max_fails=3 fail_timeout=30s;
}
参数 含义 默认值
max_fails 失败次数阈值,超过后标记为不可用 1
fail_timeout 标记不可用持续时间,期间不分配请求 10s

主动健康检查(nginx-upstream-check-module)

upstream backend {
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;

    check interval=3000 rise=2 fall=3 timeout=1000 type=http;
    check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

proxy_next_upstream 容错

proxy_next_upstream error timeout http_502 http_503 http_504;
proxy_next_upstream_timeout 10s;
proxy_next_upstream_tries 3;

五、缓冲与超时调优

Proxy 缓冲

proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
参数 含义 建议值
proxy_buffer_size 响应头缓冲区大小 4k-8k
proxy_buffers 响应体缓冲区数量和大小 8 16k
proxy_busy_buffers_size 忙时缓冲区大小 proxy_buffers 总大小的一半

超时配置

proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 30s;

client_body_timeout 12s;
client_header_timeout 12s;
send_timeout 10s;

keepalive_timeout 65s;
keepalive_requests 100;

Upstream Keepalive 连接池

upstream backend {
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    keepalive 32;
    keepalive_requests 100;
    keepalive_timeout 60s;
}

server {
    location / {
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_pass http://backend;
    }
}

keepalive 32 表示每个 Worker 与后端保持 32 个空闲长连接,避免频繁 TCP 握手。


六、Gzip 压缩优化

gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_http_version 1.1;
gzip_types
    text/plain
    text/css
    text/xml
    text/javascript
    application/json
    application/javascript
    application/xml
    application/xml+rss
    application/vnd.ms-fontobject
    application/x-font-ttf
    font/opentype
    image/svg+xml;
gzip_buffers 16 8k;
gzip_disable "msie6";
参数 说明 建议值
gzip_comp_level 压缩级别 1-9 4-6(CPU 与压缩率平衡)
gzip_min_length 最小压缩长度 1024(小文件压缩反而增大)
gzip_types 压缩的 MIME 类型 按需添加,不含图片
gzip_buffers 压缩缓冲区 16 8k

七、静态文件服务与缓存

静态文件优化

server {
    listen 80;
    server_name static.example.com;
    root /var/www/static;

    location / {
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;

        open_file_cache max=10000 inactive=20s;
        open_file_cache_valid 30s;
        open_file_cache_min_uses 2;
        open_file_cache_errors on;

        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    location ~* \.(js|css)$ {
        expires 7d;
        add_header Cache-Control "public, immutable";
    }

    location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
        expires 365d;
        add_header Cache-Control "public, immutable";
    }
}

open_file_cache 说明

参数 含义
max=N 缓存最大文件描述符数
inactive=T 缓存存活时间
valid=T 检查缓存有效性的间隔
min_uses=N 在 inactive 时间内最少访问次数
errors 是否缓存文件查找错误

八、SSL/TLS 性能优化

Session 缓存

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets on;

shared:SSL:10m 表示所有 Worker 共享 10MB 的 Session 缓存,约可缓存 40000 个会话。

OCSP Stapling

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

完整 SSL 配置

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/nginx/ssl/example.com.pem;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    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 on;

    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets on;

    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    ssl_buffer_size 4k;
}

九、限流与防护

请求速率限制(limit_req)

limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;

server {
    location /api/ {
        limit_req zone=api_limit burst=200 nodelay;
        proxy_pass http://backend;
    }
}
参数 含义
rate=100r/s 每个 IP 每秒 100 个请求
burst=200 允许突发 200 个请求
nodelay 突发请求不延迟,超过直接拒绝

并发连接数限制(limit_conn)

limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

server {
    location /api/ {
        limit_conn conn_limit 50;
        proxy_pass http://backend;
    }
}

带宽限制

location /download/ {
    limit_rate 500k;
    limit_rate_after 10m;
}

下载前 10MB 不限速,之后限速 500KB/s。


十、反向代理配置

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://backend;
        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_redirect off;
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 16k;
    }

    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 3600s;
    }
}

十一、常见错误排查

502 Bad Gateway

原因:Nginx 无法连接到后端服务。

# 检查后端服务是否运行
curl -I http://10.0.0.1:8080/health

# 检查 Nginx 错误日志
tail -f /var/log/nginx/error.log | grep 502

# 常见原因
# 1. 后端服务未启动或崩溃
# 2. 后端端口配置错误
# 3. 后端负载过高拒绝连接
# 4. SELinux/防火墙阻断

504 Gateway Timeout

原因:后端服务响应超时。

# 增大超时时间
proxy_connect_timeout 10s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
# 排查步骤
# 1. 检查后端响应时间
curl -o /dev/null -s -w "time_total: %{time_total}\n" http://backend/api
# 2. 检查后端日志是否有慢查询
# 3. 检查网络延迟
ping -c 5 10.0.0.1

429 Too Many Requests

原因:触发限流规则。

# 自定义限流响应
limit_req_status 429;

十二、安全加固

安全响应头

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'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

DDoS 防护

limit_req_zone $binary_remote_addr zone=ddos:10m rate=30r/s;
limit_conn_zone $binary_remote_addr zone=ddos_conn:10m;

server {
    limit_req zone=ddos burst=50 nodelay;
    limit_conn ddos_conn 30;

    client_body_buffer_size 16k;
    client_max_body_size 1m;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;
}

禁止敏感路径

location ~ /\.(git|svn|env) {
    deny all;
    return 404;
}

location ~* /(wp-admin|phpmyadmin|adminer) {
    deny all;
    return 404;
}

十三、性能基准测试

wrk 压测

# 安装 wrk
git clone https://github.com/wg/wrk.git
cd wrk && make && sudo cp wrk /usr/local/bin/

# 基准测试(12 线程,400 连接,持续 30 秒)
wrk -t12 -c400 -d30s http://example.com/

# 带延迟分布
wrk -t12 -c400 -d30s --latency http://example.com/

# POST 请求测试
wrk -t4 -c200 -d10s -s post.lua http://example.com/api

ab 压测

# 安装 Apache Bench
# Ubuntu: apt install apache2-utils

# 基准测试(200 并发,10000 请求)
ab -n 10000 -c 200 http://example.com/

# 带 Keep-Alive
ab -n 10000 -c 200 -k http://example.com/

压测结果分析

指标 含义 参考值
Requests/sec 每秒处理请求数 静态资源 > 10000
Latency (p99) 99% 请求延迟 < 100ms
Transfer/sec 每秒传输数据量 看业务需求
Socket errors 连接错误数 应为 0

十四、FAQ

Q: worker_processes 设为 auto 后,Worker 数量不等于 CPU 核心数?

A: auto 会读取 /proc/cpuinfo 中的可用核心数。如果容器中设置了 CPU 限额(cgroup),Nginx 1.19+ 才会感知 cgroup 限制。旧版本需手动指定。

Q: worker_connections 设为 65535 后,实际并发还是上不去?

A: 需同步修改系统限制:ulimit -nnet.core.somaxconnnet.ipv4.tcp_max_syn_backlogfs.file-max

Q: 负载均衡中 ip_hash 和一致性哈希怎么选?

A: ip_hash 简单但不支持权重和 backup,扩缩容时大量会话迁移。一致性哈希扩缩容只影响相邻节点,推荐用于缓存层。

Q: gzip_comp_level 设多少合适?

A: 4-6 是最佳区间。1-3 压缩率低,7-9 CPU 开销大但压缩率提升微乎其微。实测 level 6 相比 level 9 压缩率仅差 2-3%,但 CPU 多消耗 50%+。

Q: 如何监控 Nginx 实时状态?

A: 开启 stub_status 模块,配合 Prometheus + Grafana 或 ngxtop 工具实时监控。

location /nginx_status {
    stub_status on;
    access_log off;
    allow 127.0.0.1;
    deny all;
}

Q: 如何优雅重启 Nginx 不丢请求?

A: 使用 nginx -s reload,Master 会重新加载配置,启动新 Worker,旧 Worker 处理完当前请求后退出。


实战工具推荐:使用 /encode/base64 编码配置文件、/encode/hash 生成配置哈希校验、/json/format 格式化 Nginx JSON 日志。

本站提供浏览器本地工具,免注册即可试用 →

#Nginx#高并发#性能优化#负载均衡#教程