最可靠方式是结合lsof和/proc/pid/fd:前者统计实际打开文件数(含日志、socket等),后者直接计数内核fd条目;必须同步检查cat /proc/pid/limits中max open files软硬限,若当前值超90%即存风险。

直接查当前 worker 进程已打开的文件描述符数量,最可靠的方式是结合 lsof 和 /proc/PID/fd 两种方法,分别对应“实际打开数”和“系统视角的句柄数”。关键不是只看一个值,而是比对是否接近上限。
用 lsof 统计 worker 进程打开的文件数
先获取所有 worker 进程 PID(排除 master):
-
pgrep -f "nginx: worker process"—— 输出类似28952 28954 - 对每个 PID 执行:
lsof -p 28952 | tail -n +2 | wc -l(tail -n +2去掉表头行) - 若要一次性汇总全部 worker:
lsof -p $(pgrep -f "nginx: worker process" | tr '\n' ',' | sed 's/,$//') 2>/dev/null | tail -n +2 | wc -l
注意:非 root 用户执行时可能因权限不足漏掉部分条目,建议用 root 运行;结果包含日志文件、监听 socket、临时文件等所有打开项。
用 /proc/PID/fd 直接数句柄目录条目
这是更底层、更轻量的方式,不依赖 lsof,只统计内核已分配的实际 fd 编号:
- 任取一个 worker PID,比如
28952:ls -1 /proc/28952/fd/ 2>/dev/null | wc -l - 该命令列出
/proc/28952/fd/下所有符号链接(每个代表一个打开的 fd),直接计数即可 - 比 lsof 更快、更稳定,尤其在高负载或 lsof 卡顿时推荐此法
必须同步检查进程允许的最大值
光知道“开了多少”没用,得对比“最多能开多少”,否则无法判断风险:
- 查该 worker 进程的软硬限制:
cat /proc/28952/limits | grep "Max open files"
输出如Max open files 65535 65535 files,表示软硬限均为 65535 - 若当前打开数 > 软限制的 90%(例如 > 59000),说明逼近瓶颈,需关注 error.log 是否出现
Too many open files或accept() failed (24)
快速定位异常 worker(可选)
如果怀疑某 worker 异常占用 fd,可逐个比对:
- 批量获取各 worker 的 fd 数量:
for pid in $(pgrep -f "nginx: worker process"); do echo "PID $pid: $(ls -1 /proc/$pid/fd/ 2>/dev/null | wc -l)"; done | sort -k3 -n - 结果按打开数升序排列,一眼看出哪个 worker 明显偏高











