Nginx在高防清洗后成为最后一道可观测业务入口,其瓶颈主要是文件描述符耗尽和连接队列溢出;需调高worker_rlimit_nofile、somaxconn及backlog,并优化日志与accept策略。

高防清洗中心把流量“滤过”之后再回注到 Nginx,此时 Nginx 不是第一道防线,但却是最后一道可观测的业务入口。真正压垮它的往往不是原始攻击流量,而是清洗后残留的高并发连接、慢速请求、畸形握手,以及自身防护策略触发后的资源争抢——其中文件描述符(file descriptor)和连接队列(accept queue / listen queue)是最先触顶的两个底层瓶颈。
文件描述符耗尽:不只是“too many open files”报错
Nginx 每个连接至少占用 1 个 fd(客户端 socket),加上 upstream 连接、日志文件、共享内存区、临时文件等,实际消耗远高于并发连接数。当高防透传大量短连接或 TCP 半开连接时,fd 很快见底:
- 检查当前使用量:
lsof -p $(cat /var/run/nginx.pid) | wc -l,对比系统上限(ulimit -n或/proc/sys/fs/file-max) - 必须调高 worker 进程级限制:在 nginx.conf 的
worker_processes块外加worker_rlimit_nofile 65535; - 同步调高系统级限制:修改
/etc/security/limits.conf,对 nginx 用户设nginx soft nofile 65535和hard nofile 65535 - 避免日志刷盘拖累:启用
access_log /path/log.log buffer=64k flush=5s;,减少 write() 系统调用频次
连接队列溢出:SYN Flood 后遗症最典型的表现
即使高防已过滤掉大部分 SYN Flood,少量漏网或清洗延迟导致的密集建连,仍可能填满内核的 listen queue(即 net.core.somaxconn)。Nginx 的 accept_mutex 机制无法缓解该问题,因为队列满后内核直接丢弃 SYN ACK,客户端重传,形成恶性循环:
- 确认是否发生溢出:
ss -lnt | grep :80查看 Recv-Q 是否持续非零;netstat -s | grep "listen overflows"看累计丢包数 - 调高内核参数:
sysctl -w net.core.somaxconn=65535,并写入/etc/sysctl.conf - Nginx 配置中显式设置:
listen 80 backlog=65535;(需与 somaxconn 一致,否则无效) - 关闭
accept_mutex on(默认开启),改用accept_mutex off+multi_accept on,让每个 worker 尽可能一次 accept 多个就绪连接
压测时必须模拟的真实场景
不能只用 ab 或 wrk 直接打满 QPS,要还原高防后流量特征:
- 混合连接模式:30% 短连接(HTTP/1.0 + Connection: close)、40% 长连接(keepalive=25s)、30% TLS 握手慢速连接(用 slowhttptest 模拟 handshake timeout)
- IP 分散性控制:用 5000+ 不同源 IP(而非单 IP flood),绕过 Nginx 的 limit_conn_zone 统计,直击 fd 和 listen queue
- 加入异常流量:10% 请求头超长(>8KB)、1% 非标准 method(PROPFIND、TRACK)、0.5% 空 User-Agent —— 这些会触发 Nginx 内部解析逻辑,延长连接生命周期
- 观察指标重点:除 CPU、内存外,紧盯
/proc/net/sockstat中sockets: used和TCP:行的orphan数量(代表 TIME_WAIT + FIN_WAIT2 等未释放连接)
关联高防日志反推瓶颈归属
若压测中 Nginx 出现连接拒绝,不能默认归因于自身配置。需比对高防侧数据:
- 提取高防 API 返回的
pass_qps(透传 QPS)与 Nginxnginx_http_request_total指标差值 >15%,说明网络路径或清洗节点存在丢包或限速 - 若高防标记某 IP 段为“CC 攻击源”,但该段在 Nginx access.log 中请求速率平稳、响应时间正常,则可能是高防误判,或 Nginx 的 $binary_remote_addr 被代理覆盖(需确认
real_ip_header和set_real_ip_from配置) - 当 Nginx error.log 频繁出现
accept() failed (24: Too many open files)且listen queue overflow并存,说明 fd 和 somaxconn 同时不足,必须同步扩容


















