文件描述符限制过低是nginx ssl/tls握手频繁中断的主因,需逐层检查系统、systemd及nginx配置中的nofile限制,并监控fd实际使用与连接复用率。

当Nginx在SSL/TLS握手阶段频繁出现连接中断(如客户端报 ssl_error_syscall、connection reset by peer 或超时无响应),且日志中未见明显错误,需重点排查文件描述符(file descriptor, fd)限制是否过低——尤其在高并发HTTPS场景下,每个TLS连接在握手完成前就已占用至少1个fd,若系统级或进程级限制不足,内核会直接拒绝accept新连接,导致握手失败。
确认Nginx实际使用的文件描述符数量
不要仅依赖配置中的 worker_rlimit_nofile,需验证运行时真实消耗:
- 查Nginx主进程PID:
ps -eo pid,comm | grep nginx | grep master - 查看该进程当前打开的fd数:
ls -1 /proc/<pid>/fd/ 2>/dev/null | wc -l</pid> - 对比系统允许上限:
cat /proc/<pid>/limits | grep "Max open files"</pid>
若当前使用量接近上限(例如 >80%),且伴随 accept() failed (24: Too many open files) 出现在 error_log 中,即可确认是fd瓶颈。
逐层检查并提升文件描述符限制
限制可能存在于多个层级,需全部覆盖:
-
系统级限制:修改
/etc/security/limits.conf,为nginx用户(通常是www-data或nginx)添加两行:
nginx soft nofile 65536
nginx hard nofile 65536 -
systemd服务限制(若用systemd管理):编辑
/etc/systemd/system/nginx.service.d/override.conf,加入:
[Service]
LimitNOFILE=65536
然后执行systemctl daemon-reload && systemctl restart nginx -
Nginx配置内显式声明:在
nginx.conf的全局块中设置:
worker_rlimit_nofile 65536;
关注TLS握手对fd的额外消耗
SSL/TLS握手本身不直接“打开文件”,但以下行为会快速耗尽fd:
- 每个待握手的TCP连接在进入accept队列后即被分配一个fd,即使尚未完成ClientHello解析
- 启用OCSP Stapling时,Nginx需为每个证书定期发起上游HTTP请求(占用额外fd)
- 大量短连接+TLS 1.3 early data或session resumption,会加剧fd周转压力
建议关闭非必要功能(如 ssl_stapling off)做临时验证;若问题缓解,说明fd压力与TLS子系统强相关。
验证与长期监控
调整后不能只看是否“不报错”,要持续观测:
- 用
ss -s查看系统当前socket统计,重点关注total和timewait数量变化 - 在Nginx中开启详细连接日志:
log_format conn '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $connection $connection_requests';,结合$connection字段分析连接复用率 - 部署轻量级监控(如Prometheus + nginx-exporter),跟踪
nginx_connections_active与系统net.netstat.Tcp_CurrEstab的比值,偏离过大即提示fd调度异常











