使用场景及前置条件
应用场景:高并发 Web 服务、CDN 边缘节点、API 网关、反向代理。
前置条件:Nginx 1.15+、Linux kernel 4.18+、root 权限、pressure test 工具(wrk/ab/vegeta)。
性能目标:单机 10 万+ 并发连接、100 万+ PPS(数据包率)、P99 延迟 < 50ms。
环境
基本步骤流程
第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.somaxconn2、调整系统资源限制
查看当前资源限制
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 reload4、验证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 -205、优化后端连接复用
关键配置详解:
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性能达标检查表:
使用 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预计优化效果
优化前后对比:
最佳实践
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