并发连接数上不去是系统层、nginx配置层、网络层多环节共同限制所致,需逐级排查:先调高ulimit和sysctl内核参数(如nofile、somaxconn),再匹配worker_rlimit_nofile与worker_connections,启用epoll和multi_accept,最后用ss、stub_status等工具验证真实连接状态。

Linux + Nginx 作为静态资源服务器时,并发连接数上不去,通常不是单点问题,而是多个环节共同限制的结果。诊断要从系统层、Nginx 配置层、网络层逐级排查,调整需对应瓶颈点,不能只改 worker_connections 就完事。
检查系统级连接限制
Linux 内核对文件描述符(fd)和网络连接有默认上限,Nginx 每个连接至少占用 1 个 fd,高并发下极易触顶。
- 查看当前进程最大可打开文件数:
cat /proc/$(pgrep nginx)/limits | grep "Max open files";若显示 1024,明显不足 - 临时提升:运行
ulimit -n 65536(仅当前会话),但需持久化 —— 在/etc/security/limits.conf中添加:
nginx soft nofile 65536
nginx hard nofile 65536
并确保 systemd 启动 Nginx 时加载该配置(检查/etc/systemd/system/nginx.service.d/override.conf是否含LimitNOFILE=65536) - 确认内核参数:
net.core.somaxconn(监听队列长度)、net.core.netdev_max_backlog(网卡接收队列)建议设为 65536;net.ipv4.ip_local_port_range应覆盖足够端口范围(如1024 65535)
验证 Nginx 连接模型与核心参数
Nginx 默认使用 epoll(Linux),但配置不当仍会成为瓶颈。重点不是“能不能用”,而是“是否用对”。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 确认事件模型:
events { use epoll; }(现代 Linux 可省略,但显式写出更稳妥) -
worker_processes auto;—— 必须设为auto或匹配 CPU 核心数(避免多进程争抢) -
worker_connections 65536;—— 单个 worker 最大连接数,总理论并发 =worker_processes × worker_connections,但需受系统 ulimit 和内存制约 - 启用多路复用优化:
multi_accept on;(让 worker 尽可能一次接受多个新连接) - 关闭不必要模块:如未用 HTTPS,注释掉
ssl_protocols等相关指令,减少握手开销
观察真实连接状态与性能热点
别依赖理论值,用工具看实际发生了什么。
- 实时连接数:
ss -s | grep "TCP:"查看 ESTAB/SYN-RECV 数量;ss -tn state established | wc -l统计 ESTABLISHED 连接 - Nginx 自带状态页:启用
ngx_http_stub_status_module(编译时默认开启),在 server 块中加:
location /nginx_status { stub_status; allow 127.0.0.1; deny all; }
访问后看Active connections和Reading/Writing/Waiting分布 —— 若 Waiting 长期 > 90%,说明请求堆积在 keepalive 队列,需调优keepalive_timeout和客户端行为 - 用
perf top -p $(pgrep nginx)或pidstat -u -p $(pgrep nginx) 1观察 CPU 是否集中在 accept()、sendfile() 或 SSL 相关函数上
排除网络与客户端干扰
很多“并发上不去”其实是客户端或中间链路的问题。
- 检查是否启用了 HTTP/2:若客户端大量短连接且未复用,HTTP/1.1 的 keepalive 效率远低于 HTTP/2 多路复用;但注意 HTTP/2 对 TLS 有要求,若强制开启又没配好证书,反而增加 handshake 延迟
- 确认客户端是否过早断连:用
tcpdump -i any port 80 -w debug.pcap抓包,过滤 FIN/RST 包比例;若 RST 频繁出现,可能是客户端超时设置太短(如 curl 默认 30s),或防火墙中断长连接 - 反向代理或 CDN 层是否做了连接池限制?比如某些负载均衡器默认 max_connections=1000,会直接截断后端连接请求










