使用场景及前置条件

  • 应用场景:高并发 Web 服务、CDN 边缘节点、API 网关、反向代理。

  • 前置条件:Nginx 1.15+、Linux kernel 4.18+、root 权限、pressure test 工具(wrk/ab/vegeta)。

  • 性能目标:单机 10 万+ 并发连接、100 万+ PPS(数据包率)、P99 延迟 < 50ms。

环境

组件

推荐版本

最小要求

性能影响

Nginx

1.24+

1.15+

LTS 版本更稳定

内核

5.10+

4.18+

新内核性能提升 10-20%

CPU

万兆网卡配置

千兆

网卡是瓶颈

内存

4GB+

2GB+

缓冲池/连接池

文件描述符

ulimit -n 100000+

65535+

连接数上限

网络栈优化

net.ipv4.* 调优

默认

丢包/延迟显著改善

基本步骤流程

  • 第1步:优化 Linux 内核网络参数(sysctl)。

  • 第2步:调整系统资源限制(ulimit、文件描述符)。

  • 第3步:优化 Nginx 进程模型与连接处理。

  • 第4步:配置高效的 I/O 多路复用机制。

  • 第5步:优化后端连接复用与超时策略。

  • 第6步:启用 HTTP/2 与 gzip 动态压缩。

  • 第7步:进行基准测试与性能验证。

  • 第8步:构建监控告警体系。

具体实施步骤

1、优化linux内核网络参数

编辑sysctl文件

sudo vi /etc/sysctl.conf

完整优化参数

# ============ TCP 连接参数 ============
# 增加 TCP 等待队列大小(处理突发连接)
net.core.somaxconn = 65535
# SYN 等待队列大小(防 SYN Flood)
net.ipv4.tcp_max_syn_backlog = 65535
# TIME_WAIT 连接数上限(高并发必需)
net.ipv4.tcp_max_tw_buckets = 1000000

# ============ TIME_WAIT 管理 ============
# 允许 TIME_WAIT 连接复用
net.ipv4.tcp_tw_reuse = 1
# TIME_WAIT 超时时间(秒)
net.ipv4.tcp_fin_timeout = 30
# 关闭 TIME_WAIT 安全检查(充分信任内网)
net.ipv4.tcp_tw_recycle = 0

# ============ 连接追踪 ============
# 增加连接追踪表大小(NAT/LB 必需)
net.netfilter.nf_conntrack_max = 2000000
net.netfilter.nf_conntrack_tcp_timeout_established = 600
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 60

# ============ 端口范围 ============
# 扩大动态端口范围(减少 TIME_WAIT 冲突)
net.ipv4.ip_local_port_range = 1024 65535

# ============ TCP 保活 ============
# TCP 保活探针发送间隔(秒)
net.ipv4.tcp_keepalive_time = 300
# 保活探针失败重试次数
net.ipv4.tcp_keepalive_probes = 5
# 保活探针重试间隔(秒)
net.ipv4.tcp_keepalive_intvl = 30

# ============ TCP 滑动窗口 ============
# 启用 TCP 窗口伸缩
net.ipv4.tcp_window_scaling = 1
# 启用 TCP 时间戳
net.ipv4.tcp_timestamps = 1

# ============ 缓冲区 ============
# TCP 发送缓冲区大小(字节)
net.ipv4.tcp_wmem = 4096 65536 16777216
# TCP 接收缓冲区大小(字节)
net.ipv4.tcp_rmem = 4096 65536 16777216
# UDP 缓冲区大小
net.ipv4.udp_mem = 94500000 1300000000 2000000000

# ============ 网络驱动优化 ============
# 网卡队列长度
net.core.netdev_max_backlog = 65535
# socket 接收缓冲区最大值
net.core.rmem_max = 33554432
# socket 发送缓冲区最大值
net.core.wmem_max = 33554432
# socket 默认接收缓冲区
net.core.rmem_default = 8388608
# socket 默认发送缓冲区
net.core.wmem_default = 8388608

# ============ IP 转发与 ICMP ============
# 关闭 ICMP 重定向(加速转发)
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# 启用 ECMP(Equal-Cost Multi-Path)路由
net.ipv4.fib_multipath_hash_policy = 1

# ============ TCP 优化 ============
# 启用 TCP Fast Open(TFO)
net.ipv4.tcp_fastopen = 3
# 启用 MTU 探测
net.ipv4.tcp_mtu_probing = 1

应用生效验证

sudo sysctl -p

sysctl net.ipv4.tcp_tw_reuse
sysctl net.core.somaxconn

2、调整系统资源限制

查看当前资源限制

ulimit -a

预期输出

open files                      (-n) 1024   ← 需要调整到 65535+
max locked memory               (-l) 64

临时调整(当前会话)

ulimit -n 100000
ulimit -s unlimited

永久调整(所有用户)

# 在文件中添加下面参数
sudo vi /etc/security/limits.conf
*    soft  nofile  100000
*    hard  nofile  100000
*    soft  nproc   100000
*    hard  nproc   100000
*    soft  memlock unlimited
*    hard  memlock unlimited

如果想对nginx用户单独配置

nginx    soft  nofile  100000
nginx    hard  nofile  100000
nginx    soft  nproc   65535
nginx    hard  nproc   65535

验证

ulimit -n 

3、优化nginx进程模型

# 编辑nginx配置文件
sudo vi /etc/nginx/nginx.conf

user nginx nginx;

# 启用自动检测 CPU 核心数(绑定 worker 进程)
worker_processes auto;

# 绑定 worker 进程到特定 CPU 核心(减少缓存失效)
worker_cpu_affinity auto;

# 优先级(-10 为最高,减少上下文切换)
worker_priority -10;

# 文件描述符限制(必须大于连接数)
worker_rlimit_nofile 100000;

# 定时器分辨率(毫秒)
timer_resolution 1ms;

events {
    # 单 worker 最大并发连接数
    worker_connections 65535;

    # I/O 多路复用方式(Linux 下默认 epoll)
    use epoll;

    # 是否多次 accept 连接
    multi_accept on;

    # 是否使用 accept_mutex(高并发关闭以避免锁竞争)
    accept_mutex off;
}

http {
    # ============ 基础设置 ============
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # ============ 日志格式 ============
    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';

    # 禁用日志(高性能,但影响诊断)
    # access_log off;

    # 异步日志(减少 I/O 等待)
    access_log /var/log/nginx/access.log main buffer=32k flush=5s;

    # ============ 性能优化 ============
    # 启用 sendfile(零拷贝)
    sendfile on;

    # TCP_NOPUSH(减少网卡中断)
    tcp_nopush on;

    # TCP_NODELAY(降低延迟)
    tcp_nodelay on;

    # 连接保活超时
    keepalive_timeout 65;

    # 请求头大小限制
    client_max_body_size 100m;

    # ============ 压缩 ============
    # 启用 gzip 压缩
    gzip on;
    # 最小压缩大小(小于此值不压缩)
    gzip_min_length 1k;
    # 压缩级别(1-9,6 为平衡)
    gzip_comp_level 6;
    # 压缩类型
    gzip_types text/plain text/css text/xml text/javascript application/json;
    # 启用 Vary 响应头
    gzip_vary on;

    # ============ 上游连接 ============
    # 后端服务器定义
    upstream backend {
        # 最少连接算法(比轮询更优)
        least_conn;

        # 启用 Keep-Alive(连接复用)
        keepalive 256;

        server 192.168.1.10:8080 max_fails=3 fail_timeout=30s weight=1;
        server 192.168.1.11:8080 max_fails=3 fail_timeout=30s weight=1;
        server 192.168.1.12:8080 max_fails=3 fail_timeout=30s weight=1;
    }

    # ============ 虚拟主机 ============
    server {
        listen 80 default_server reuseport backlog=65535;
        listen [::]:80 default_server reuseport;

        server_name _;

        # ============ 路由与代理 ============
        location / {
            proxy_pass http://backend;

            # HTTP 版本(1.1 支持 Keep-Alive)
            proxy_http_version 1.1;

            # 头部配置
            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;

            # 关键:清空 Connection 头实现连接复用
            proxy_set_header Connection "";

            # 超时配置
            proxy_connect_timeout 10s;
            proxy_send_timeout 30s;
            proxy_read_timeout 30s;

            # 缓存配置
            proxy_buffering on;
            proxy_buffer_size 8k;
            proxy_buffers 8 8k;

            # 热连接保活
            proxy_socket_keepalive on;
        }

        # 健康检查端点
        location /health {
            access_log off;
            return 200 "ok\n";
            add_header Content-Type text/plain;
        }

        # 性能监控(需要编译 --with-http_stub_status_module)
        location /nginx_status {
            stub_status on;
            access_log off;
            allow 127.0.0.1;
            deny all;
        }
    }
}

验证并加载

sudo nginx -t 
sudo nginx -s reload

4、验证I/O多路复用

查看编译参数(确认支持 epoll):

nginx -V 2>&1 | grep -i event

预期输出:--with-poll_module --with-epoll_module

验证 Nginx 使用的事件模型:

sudo strace -p $(pgrep nginx | head -1) -e trace=poll,epoll_wait,select -c 2>&1 | head -20

5、优化后端连接复用

关键配置详解:

upstream backend {
    # 连接池大小(单 worker 的后端连接数)
    keepalive 256;

    # 最少连接算法(负载更均衡)
    least_conn;

    server backend1:8080;
    server backend2:8080;
}

server {
    location / {
        proxy_pass http://backend;

        # 必须设置为 1.1 启用 Keep-Alive
        proxy_http_version 1.1;

        # 关键:清空 Connection 头(否则会传递 close)
        proxy_set_header Connection "";

        # 启用后端连接 keepalive
        proxy_socket_keepalive on;
    }
}

验证连接复用有效性:

# 监控后端连接状态
sudo netstat -ant | grep backend | wc -l

# 预期:远小于发起的请求数(因为连接被复用)

6、启动http/2与动态压缩

编译 HTTP/2 支持(如未启用):

# 检查是否支持 HTTP/2
nginx -V 2>&1 | grep http_v2

# 如无 http_v2,需重新编译
./configure --with-http_v2_module
make && sudo make install

配置 HTTP/2:

server {
    listen 443 ssl http2 reuseport;

    # SSL 证书配置
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # SSL 优化
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
}

启用动态 gzip 压缩:

gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript application/json;
# 禁用对旧浏览器的压缩(兼容性)
gzip_disable "msie6";
# 添加 Vary 头
gzip_vary on;

7、基准测试与性能验证

使用 wrk 压测:

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

# 执行压测(4 线程、100 并发连接、30 秒)
wrk -t4 -c100 -d30s --latency http://localhost/health

预期输出示例:

Running 30s test @ http://localhost/health
  4 threads and 100 connections
Latencies
  Avg        Stdev      Max
  2.34ms     1.20ms     45.32ms
Requests/sec: 42811.23
Transfer/sec: 6.48MB

Percentiles:
  50%        2.12ms
  90%        3.45ms
  99%        8.23ms
  99.9%     15.67ms

性能达标检查表:

指标

目标值

说明

Requests/sec

> 50,000

单机吞吐量

Latency Avg

< 5ms

平均响应时间

Latency P99

< 20ms

99% 用户体验

Max Latency

< 100ms

异常值

错误率

0%

无异常响应

使用 ab(ApacheBench)压测:

# 1000 请求,50 并发
ab -n 1000 -c 50 -t 30 http://localhost/

8、构建监控告警

Prometheus 采集配置:

scrape_configs:
  - job_name: 'nginx'
    static_configs:
      - targets: ['localhost:9113']

关键监控指标:

nginx_requests_total{method="GET"}
nginx_requests_total{status="2xx|4xx|5xx"}
nginx_connection_accepted_total
nginx_connection_active
nginx_connection_waiting
nginx_upstream_requests_total
nginx_upstream_response_time_seconds

告警规则示例:

- alert: NginxHighErrorRate
  expr: rate(nginx_requests_total{status=~"5.."}[5m]) > 0.05
  for: 5m

- alert: NginxHighLatency
  expr: histogram_quantile(0.99, nginx_upstream_response_time_seconds) > 0.5
  for: 5m

- alert: NginxConnectionDrain
  expr: nginx_connection_active > 100000
  for: 2m

预计优化效果

优化前后对比:

指标

优化前

优化后

提升倍数

单机 QPS

5 万

50 万

10×

P99 延迟

100ms

5ms

20×

内存占用

2GB

2.5GB

1.25×

CPU 使用率

85%

75%

11.8% 降低

最佳实践

  • 1. 参数隔离:内核参数、系统限制、Nginx 配置分层管理。

  • 2. 压测验证:任何优化前后都要测试,避免盲目调参。

  • 3. 监控先行:建立基准监控,对比优化效果。

  • 4. 连接复用:后端连接必须配置 keepalive,否则性能骤降 50%。

  • 5. 异步日志:高并发环境下启用异步日志减少 I/O 阻塞。

  • 6. CPU 亲和性:绑定 worker 到 CPU 核心,减少进程迁移。

  • 7. 定期审计:每月检查 sysctl 参数与 ulimit,确保生效。

优化清单

# 1. 系统参数一键优化
cat >> /etc/sysctl.conf <<EOF
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_tw_buckets = 1000000
net.ipv4.ip_local_port_range = 1024 65535
EOF
sudo sysctl -p

# 2. 文件描述符一键调整
sudo sed -i 's/^#.*soft.*nofile.*/\*  soft  nofile  100000/' /etc/security/limits.conf
sudo sed -i 's/^#.*hard.*nofile.*/\*  hard  nofile  100000/' /etc/security/limits.conf

# 3. 验证优化
sysctl -a | grep somaxconn
ulimit -n

# 4. Nginx 配置检查
sudo nginx -t

# 5. 压测验证
wrk -t4 -c100 -d30s http://localhost/

总结:Nginx 高并发优化不是单点调整,而是系统工程。关键是:内核网络参数优化(缓冲、连接追踪、TIME_WAIT 复用)+ 系统资源限制调整(ulimit) + Nginx 进程模型优化(worker 绑定、连接复用) + 后端连接复用(keepalive)+ 实时监控反馈。掌握这五个维度,性能可以从 5 万 QPS 提升到 50 万 QPS,P99 延迟从 100ms 降低到 5ms

参考链接:

https://mp.weixin.qq.com/s/6Vm63ujuS9jC-PPHLYkxYw