作为工作的一部分,我使用几个不同的 Nodejs 实时服务器,并且我的工具/工作流程中似乎存在某种泄漏,导致文件观察程序随着时间的推移而累积,直到达到系统限制。然后我收到以下 cli 错误:
Error from chokidar (<path-to-folder>): Error:
ENOSPC: System limit for number of file watchers reached, watch '<path-to-folder>/<filename>'
我发现以下命令应该返回使用的 wile 观察者的数量:
find /proc/*/fd -user "$USER" -lname anon_inode:inotify -printf '%hinfo/%f\n' 2>/dev/null | xargs cat | grep -c '^inotify'
它返回 515160,尽管我似乎已经关闭了所有实时服务器。我有两组问题:
- 我该如何诊断这个问题?我可以获取所有注册观察者的列表、他们的观察路径和相应的 PID 或类似的信息吗?
- 我有办法把他们全部杀掉吗?杀死所有文件观察者是个好主意吗?我可以只杀死我的服务器注册的观察者吗?
我运行的是 Debian 11
答案1
您提供的命令正在搜索其中有符号链接的/proc
任何文件描述符。报告这些进程的命令和 PID,以及设置的监视数量也非常简单:/proc/*/fd/
anon_inode:inotify
#!/bin/bash
cd /proc
for p in [0-9]*
do cd $p
if find fd -user "$USER" -lname anon_inode:inotify 2>/dev/null | grep -q .
then IFS= read -d '' cmd < cmdline
numwatch=$(cat fdinfo/* | grep -c '^inotify')
[[ $numwatch -ge 1 ]] && printf '%s\n PID %s\t %s watches\n' "$cmd" "$p" "$numwatch"
fi
cd ..
done
其实我发现oligofren已经写过类似的脚本了,inotify-消费者, 作为 一个答案它有更漂亮的格式输出。
然而,找到被监视的实际路径却是更复杂。您只有来自 的 inode /proc/*/fdinfo
,因此您必须搜索整个文件系统以找到映射到 inode 的路径。这是一项昂贵的操作。
有一个C++程序inotify-信息哪个执行此操作;还发现自这里有一个答案。我刚刚在我的机器上构建了它并且它可以工作。不带参数运行,它只是列出每个进程的监视数量,与 inotify-consumers 脚本相同。给定特定的命令名称或 PID,它还会搜索该进程监视的 inode 的路径。
杀死所有观察者可能不是一个好主意,但是在查看哪些进程正在使用大量观察者之后,您可以做出明智的选择。