Py学习  »  NGINX

Nginx 反向代理超时优化与连接池调优 10 分钟落地实战

马哥Linux运维 • 2 周前 • 62 次点击  

Nginx 反向代理超时优化与连接池调优 10 分钟落地实战

适用场景 & 前置条件

适用业务:高并发 Web 应用、API 网关、微服务代理(QPS > 1000)OS/内核要求:Linux 3.10+(RHEL/CentOS 7+ 或 Ubuntu 18.04+)Nginx 版本:1.18.0+ / 1.20.0+(支持动态连接池)网络/端口:80/443(对外)、上游服务端口可达权限要求:root 或 sudo 权限(修改配置与重载)依赖组件:已安装 nginxcurlssab/wrk 压测工具

环境与版本矩阵

组件
版本/规格
说明
OS
RHEL 8.x / Ubuntu 20.04 LTS
内核 4.18+ / 5.4+
Nginx
1.20.2 / 1.22.1
支持 keepaliveproxy_next_upstream_timeout
CPU
4 Core 最小
建议 8 Core(高并发场景)
Memory
8 GB 最小
建议 16 GB
上游服务
HTTP/HTTPS
支持 Keep-Alive
网络带宽
100 Mbps+
内网 1 Gbps+

快速清单(Checklist)

  • • [ ] 备份当前 Nginx 配置文件
  • • [ ] 检查现有超时参数与连接池配置
  • • [ ] 配置上游连接池(keepalive)
  • • [ ] 调整 proxy_timeout 系列参数
  • • [ ] 配置 TCP Fast Open 与系统参数
  • • [ ] 测试配置语法与重载 Nginx
  • • [ ] 压测验证连接复用率与响应时间
  • • [ ] 监控连接数与超时错误
  • • [ ] 准备回滚方案(保留旧配置)

实施步骤(核心内容)

Step 1:备份现有配置并检查当前状态

RHEL/CentOS:

cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%Y%m%d%H%M)
cp /etc/nginx/conf.d/proxy.conf /etc/nginx/conf.d/proxy.conf.bak.$(date +%Y%m%d%H%M)

Ubuntu/Debian:

cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%Y%m%d%H%M)
cp /etc/nginx/sites-enabled/default /etc/nginx/sites-enabled/default.bak.$(date +%Y%m%d%H%M)

检查当前连接状态:

# 查看当前 Nginx 进程与连接数
ps aux | grep nginx
ss -tan | grep :80 | wc -l

# 查看当前配置中的超时参数
grep -E 'proxy_.*timeout|keepalive' /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf

预期输出示例:

worker_processes auto;
# 可能缺少 keepalive 配置或超时值过大
proxy_connect_timeout 60s;
proxy_read_timeout 60s;

关键参数解释:

  • • worker_processes auto:自动匹配 CPU 核心数
  • • 默认超时 60s 对快速 API 过长,需调整至 5-10s
  • • 缺少 keepalive 导致每次请求建立新连接

Step 2:配置上游连接池(upstream + keepalive)

编辑上游配置文件:

vi /etc/nginx/conf.d/upstream.conf

配置内容(适用 Nginx 1.20+):

upstream backend_api {
# 上游服务器列表
server192.168.1.101:8080 max_fails=3 fail_timeout=30s;
server192.168.1.102:8080 max_fails=3 fail_timeout=30s;

# 连接池配置(核心)
keepalive128;                    # 每个 worker 保持 128 个空闲连接
keepalive_requests1000;          # 单连接最多处理 1000 个请求后关闭
keepalive_timeout60s;            # 空闲连接保持 60 秒

# 负载均衡算法
    least_conn;                       # 最少连接优先(高并发推荐)
}

关键参数解释:

  • • keepalive 128:连接池大小 = worker 数 × 目标并发 / 上游节点数(示例:4 worker × 64 并发 / 2 节点 = 128)
  • • keepalive_requests 1000:防止长连接资源泄漏
  • • least_conn:动态负载均衡,避免短连接风暴

执行前校验:

# 测试配置语法
nginx -t

预期输出:

nginx: configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Step 3:调整反向代理超时参数

编辑 server 配置块:

vi /etc/nginx/conf.d/proxy.conf

配置内容:

server {
listen80;
server_name api.example.com;

location /api/ {
proxy_pass http://backend_api;

# 超时优化(核心)
proxy_connect_timeout5s;        # 建立连接超时(默认 60s → 5s)
proxy_send_timeout10s;          # 发送请求超时(默认 60s → 10s)
proxy_read_timeout10s;          # 读取响应超时(默认 60s → 10s)
proxy_next_upstream_timeout5s;  # 故障转移总超时
proxy_next_upstreamerror timeout http_502 http_503 http_504;

# 连接池复用(关键)
proxy_http_version1.1;
proxy_set_header Connection "";  # 清除 Connection: close

# Header 传递
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_bufferingon;
proxy_buffer_size8k;
proxy_buffers328k;
proxy_busy_buffers_size16k;
    }
}

关键参数解释:

  • • proxy_http_version 1.1 + Connection "":强制使用 HTTP/1.1 长连接
  • • proxy_connect_timeout 5s:快速失败,避免阻塞后续请求
  • • proxy_next_upstream:自动重试机制(502/503/504 错误转发至其他节点)

执行前后校验:

# 配置生效前测试连接
curl -w "@curl-format.txt" -o /dev/null -s http://api.example.com/api/test

# 重载配置
nginx -s reload

# 配置生效后测试
curl -w "@curl-format.txt" -o /dev/null -s http://api.example.com/api/test

curl-format.txt 内容:

time_namelookup:  %{time_namelookup}\n
time_connect:     %{time_connect}\n
time_starttransfer: %{time_starttransfer}\n
time_total:       %{time_total}\n

预期对比:

  • • time_connect 从 0.1s 降至 0.001s(连接复用生效)
  • • time_total 降低 10-30%

Step 4:系统内核参数优化(TCP Fast Open + 连接队列)

编辑 sysctl 配置:

vi /etc/sysctl.d/99-nginx-tuning.conf

配置内容:

# TCP Fast Open(减少握手延迟)
net.ipv4.tcp_fastopen = 3

# 连接队列
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192

# TIME_WAIT 优化
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30

# 连接池相关
net.ipv4.ip_local_port_range = 1000065535
net.ipv4.tcp_max_tw_buckets = 10000

# Keep-Alive 优化
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3

应用配置:

sysctl -p /etc/sysctl.d/99-nginx-tuning.conf

# 验证参数生效
sysctl net.ipv4.tcp_fastopen
sysctl net.core.somaxconn

预期输出:

net.ipv4.tcp_fastopen = 3
net.core.somaxconn = 65535

Nginx 启用 TCP Fast Open:

# 在 listen 指令中添加 fastopen
listen80 fastopen=256 reuseport;

关键参数解释:

  • • tcp_fastopen = 3:客户端与服务端同时启用(1=客户端,2=服务端,3=双向)
  • • somaxconn = 65535:监听队列长度(默认 128 不足以支撑高并发)
  • • tcp_tw_reuse = 1:允许 TIME_WAIT 连接复用(仅客户端有效)

Step 5:压测验证连接复用率与性能提升

使用 wrk 压测(并发 200,持续 30 秒):

wrk -t4 -c200 -d30s --latency http://api.example.com/api/test

优化前预期输出:

Running 30s test @ http://api.example.com/api/test
  4 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    85.23ms   42.15ms   500.00ms   68.72%
    Req/Sec   580.12    120.45     1.20k    71.23%
  69452 requests in 30.02s, 12.34MB read
Requests/sec: 2314.56
Transfer/sec: 420.78KB

优化后预期输出:

Running 30s test @ http://api.example.com/api/test
  4 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    32.15ms   18.23ms   250.00ms   72.45%
    Req/Sec   1520.34   215.67     2.10k    68.91%
  182345 requests in 30.01s, 32.45MB read
Requests/sec: 6078.23
Transfer/sec: 1.08MB

关键指标对比:

  • • QPS:2314 → 6078(提升 162%)
  • • P99 延迟:500ms → 250ms(降低 50%)
  • • 连接复用率检查命令:
# 查看 ESTABLISHED 连接数(应稳定在 keepalive 设定值附近)
ss -tan | grep ESTAB | grep :80 | wc -l

# 查看 TIME_WAIT 连接数(应显著减少)
ss -tan | grep TIME-WAIT | wc -l

预期对比:

  • • ESTABLISHED:从 2000+ 降至 128-256(连接复用生效)
  • • TIME_WAIT:从 5000+ 降至 500-(短连接减少)

Step 6:配置 Nginx Stub Status 监控

启用状态页:

server {
listen8080;
server_name localhost;

location /nginx_status {
stub_statuson;
access_logoff;
allow127.0.0.1;
deny all;
    }
}

重载配置并测试:




    
nginx -s reload
curl http://127.0.0.1:8080/nginx_status

预期输出:

Active connections: 245
server accepts handled requests
 1234567 1234567 8901234
Reading: 5 Writing: 10 Waiting: 230

关键指标解释:

  • • Active connections:当前活跃连接数
  • • Waiting:处于 Keep-Alive 状态的空闲连接数(应接近 keepalive 配置值)
  • • accepts = handled:无连接溢出

监控与告警(立即可用)

Prometheus + Nginx Exporter

安装 nginx-prometheus-exporter:

# RHEL/CentOS
wget https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/v0.11.0/nginx-prometheus-exporter_0.11.0_linux_amd64.tar.gz
tar -xzf nginx-prometheus-exporter_0.11.0_linux_amd64.tar.gz -C /usr/local/bin/

# 启动 exporter(假设 stub_status 在 8080)
/usr/local/bin/nginx-prometheus-exporter -nginx.scrape-uri=http://127.0.0.1:8080/nginx_status

Prometheus 抓取配置:

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

关键 PromQL 查询:

# 连接复用率
rate(nginx_connections_accepted[5m]) - rate(nginx_connections_handled[5m])

# 活跃连接数
nginx_connections_active

# 等待连接数(Keep-Alive 池)
nginx_connections_waiting

# 请求速率
rate(nginx_http_requests_total[5m])

Grafana 告警阈值建议:

  • • 活跃连接 > 10000:容量告警
  • • 等待连接 < 50:连接池未生效
  • • 连接溢出(accepts != handled)> 0:队列不足

Linux 原生监控命令

实时连接数监控:

watch -n1 'ss -tan | grep :80 | wc -l'

连接状态分布:




    
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn

预期健康输出:

    230 ESTAB        # 稳定在连接池大小附近
     50 TIME-WAIT    # 优化后显著减少
      5 SYN-SENT

性能与容量(可复制)

基准测试命令

短连接 vs 长连接对比:

# 短连接测试(未优化)
ab -n 10000 -c 100 http://api.example.com/api/test

# 长连接测试(优化后)
ab -n 10000 -c 100 -k http://api.example.com/api/test

预期提升:

  • • QPS:3000 → 8000(+166%)
  • • 平均响应时间:33ms → 12ms(-63%)

目标指标(生产级)

指标
优化前
优化后
备注
QPS
2000-3000
6000-10000
4 核 CPU
P99 延迟
300-500ms
50-100ms
上游 RT < 20ms
连接数
2000-5000
200-500
连接复用生效
CPU 使用率
60-80%
30-50%
减少握手开销

调优参数矩阵(按并发分级)

并发等级
keepalive
worker_processes
worker_connections
低(< 1K QPS)
64
2
4096
中(1-5K QPS)
128
4
8192
高(5-10K QPS)
256
8
16384
超高(> 10K QPS)
512
auto
32768

安全与合规(最小必需)

访问控制

限制状态页访问:

location /nginx_status {
stub_statuson;
allow10.0.0.0/8;       # 内网段
allow192.168.0.0/16;
deny all;
}

超时防护

防止慢速攻击:

# 客户端超时保护
client_body_timeout10s;
client_header_timeout10s;
send_timeout10s;

# 限制请求速率
limit_req_zone$binary_remote_addr zone=api_limit:10m rate=100r/s;
limit_req zone=api_limit burst=200 nodelay;

审计日志

记录超时与错误:

log_format proxy_log '$remote_addr - $remote_user [$time_local] '
'"$request$status$body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'upstream: $upstream_addr '
'request_time: $request_time '
'upstream_response_time: $upstream_response_time '
'upstream_connect_time: $upstream_connect_time';

access_log /var/log/nginx/proxy_access.log proxy_log;

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

常见故障与排错

症状
诊断命令
可能根因
快速修复
永久修复
QPS 无提升
ss -tan | grep ESTAB
连接未复用(未配置  proxy_http_version 1.1
检查 Connection "" 是否配置
补齐 upstream keepalive 配置
502 Bad Gateway
grep "upstream" /var/log/nginx/error.log
上游超时/连接池耗尽
增大 keepalive 至 256
扩容上游节点或优化后端性能
连接数持续增长
ss -tan | grep TIME-WAIT | wc -lkeepalive_requests
 过大或未设置
设置 keepalive_requests 1000
启用 tcp_tw_reuse
CPU 使用率高
top -Hp $(pidof nginx)
worker 进程不足
调整 worker_processes auto
优化 worker_cpu_affinity
压测 QPS 不稳定
dmesg | grep -i socketsomaxconn
 队列溢出
sysctl -w net.core.somaxconn=65535
写入 /etc/sysctl.conf
部分请求超时
tcpdump -i any port 8080
上游服务未启用 Keep-Alive
检查上游 HTTP 响应头 Connection
修改上游服务配置支持长连接

变更与回滚剧本

维护窗口建议

  • • 低峰时段(凌晨 2-4 点)
  • • 灰度节点先行(10% → 50% → 100%)

灰度策略

使用 split_clients 模块:

split_clients$remote_addr$backend_pool {
    10%     backend_api_new;  # 新配置
    *       backend_api_old;   # 旧配置
}

location /api/ {
proxy_pass http://$backend_pool;
}

健康检查

配置前置检查脚本:

#!/bin/bash
# health_check.sh

nginx -t || exit 1

# 测试上游可达性
for server in 192.168.1.101:8080 192.168.1.102:8080; do
    curl -sf http://$server/health || {
echo"Upstream $server unhealthy"
exit 1
    }
done

echo"Health check passed"

回滚命令(1 分钟内完成)

# 立即回滚至备份配置
cp /etc/nginx/nginx.conf.bak.YYYYMMDDHHMM /etc/nginx/nginx.conf
cp /etc/nginx/conf.d/proxy.conf.bak.YYYYMMDDHHMM /etc/nginx/conf.d/proxy.conf

# 验证配置并重载
nginx -t && nginx -s reload

# 确认连接数恢复
ss -tan | grep :80 | wc -l

数据备份

监控数据快照:

# 变更前记录基线指标
curl http://127.0.0.1:8080/nginx_status > /tmp/nginx_status.before
ss -tan > /tmp/ss_output.before

最佳实践(10 条要点)

  1. 1. 连接池上限keepalive = worker_processes × 目标并发 / 上游节点数(示例:4×64/2=128)
  2. 2. 超时梯度connect < send/read < next_upstream(5s < 10s < 15s)
  3. 3. 限流配合:使用 limit_req 防止突发流量击穿连接池
  4. 4. 上游健康检查:启用 max_fails=3 fail_timeout=30s 自动摘除故障节点
  5. 5. 日志分级:error_log 使用 warn 避免性能影响,关键指标用 access_log 记录
  6. 6. 系统参数优先级:先调 somaxconn 与 tcp_fastopen,再优化应用层
  7. 7. 长连接保活keepalive_timeout 设置 60-120s(与上游一致)
  8. 8.  避免过度优化:单 worker 连接池 > 512 时考虑垂直扩容
  9. 9. 版本兼容性:Nginx 1.20+ 才支持 keepalive_requests,旧版需升级
  10. 10. 监控闭环:部署 Prometheus + Grafana 实时跟踪 nginx_connections_waiting

附录(样例资产)

完整 upstream 配置样例

upstream backend_api {
server192.168.1.101:8080 weight=1 max_fails=3 fail_timeout=30s;
server192.168.1.102:8080 weight=1 max_fails=3 fail_timeout=30s;
server192.168.1.103:8080 weight=2 max_fails=3 fail_timeout=30s backup;

keepalive256;
keepalive_requests1000;
keepalive_timeout75s;

    least_conn;
}

完整 location 配置样例

location /api/ {
proxy_pass http://backend_api;

# 超时优化
proxy_connect_timeout5s;
proxy_send_timeout10s;
proxy_read_timeout10s;
proxy_next_upstream_timeout15s;
proxy_next_upstreamerror timeout http_502 http_503 http_504;

# 连接池复用
proxy_http_version1.1;
proxy_set_header Connection "";

# Header 传递
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_bufferingon;
proxy_buffer_size8k;
proxy_buffers328k;
proxy_busy_buffers_size16k;

# 限流保护
limit_req zone=api_limit burst=200 nodelay;

# 日志记录
access_log /var/log/nginx/api_access.log proxy_log;
}

sysctl 完整配置样例

# /etc/sysctl.d/99-nginx-tuning.conf

# TCP Fast Open
net.ipv4.tcp_fastopen = 3

# 连接队列
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 8192
net.ipv4.tcp_max_syn_backlog = 8192

# TIME_WAIT 优化
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_max_tw_buckets = 10000

# 端口范围
net.ipv4.ip_local_port_range = 1000065535

# Keep-Alive 优化
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3

# 拥塞控制
net.core.rmem_max = 16777216
net.core.wmem_max  = 16777216
net.ipv4.tcp_rmem = 40968738016777216
net.ipv4.tcp_wmem = 40966553616777216

Ansible 自动化部署任务

---
-name:OptimizeNginxReverseProxy
hosts:nginx_servers
become:yes

tasks:
-name:BackupcurrentNginxconfig
copy:
src:/etc/nginx/nginx.conf
dest:"/etc/nginx/nginx.conf.bak.{{ ansible_date_time.epoch }}"
remote_src:yes

-name:Deployoptimizedupstreamconfig
template:
src:templates/upstream.conf.j2
dest:/etc/nginx/conf.d/upstream.conf
notify:reloadnginx

-name:Deployoptimizedproxyconfig
template:
src:templates/proxy.conf.j2
dest:/etc/nginx/conf.d/proxy.conf
notify:reloadnginx

-name:Applysysctltuning
sysctl:
name:"{{ item.name }}"
value:"{{ item.value }}"
state:present
reload:yes
loop:
- { name:'net.ipv4.tcp_fastopen'value:'3' }
- { name:'net.core.somaxconn'value:'65535' }
- { name:'net.ipv4.tcp_tw_reuse'value:'1' }

-name:ValidateNginxconfig
command:nginx-t
changed_when:false

handlers:
-name:reloadnginx
service:
name:nginx
state:reloaded

测试于 2025-10,Nginx 1.22.1,RHEL 8.7 / Ubuntu 20.04

文末福利


网络监控是保障网络系统和数据安全的重要手段,能够帮助运维人员及时发现并应对各种问题,及时发现并解决,从而确保网络的顺畅运行。

谢谢一路支持,给大家分享6款开源免费的网络监控工具,并准备了对应的资料文档,建议运维工程师收藏(文末一键领取)。

图片
备注:【监控合集】

图片

100%免费领取


一、zabbix

图片
图片

二、Prometheus


图片

内容较多,6款常用网络监控工具(zabbix、Prometheus、Cacti、Grafana、OpenNMS、Nagios不再一一介绍, 需要的朋友扫码备注【监控合集】,即可100%免费领取。

图片

 以上所有资料获取请扫码

备注:【监控合集】

图片

100%免费领取

(后台不再回复,扫码一键领取)


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/188569