最近我遇到了一个Linux进程"泄漏"文件描述符的问题:它打开了这些文件描述符,但没有正确地关闭其中一部分。
如果我监控这个进程,我可以提前得知该进程正在接近其极限。
在Ubuntu Linux系统中,是否有一种不错的Bash或Python方法来检查给定进程的FD使用率?
编辑:
我现在知道如何检查有多少个打开的文件描述符;我只需要知道一个进程允许有多少个文件描述符。有些系统(如Amazon EC2)没有/proc/pid/limits
文件。
最近我遇到了一个Linux进程"泄漏"文件描述符的问题:它打开了这些文件描述符,但没有正确地关闭其中一部分。
如果我监控这个进程,我可以提前得知该进程正在接近其极限。
在Ubuntu Linux系统中,是否有一种不错的Bash或Python方法来检查给定进程的FD使用率?
编辑:
我现在知道如何检查有多少个打开的文件描述符;我只需要知道一个进程允许有多少个文件描述符。有些系统(如Amazon EC2)没有/proc/pid/limits
文件。
统计 /proc/<pid>/fd/
目录下的文件或目录数量。进程所应用的硬限制和软限制可以在 /proc/<pid>/limits
中找到。
getrlimit()
和/proc/
pid/limits
。getrlimit()
只能获取调用进程的资源限制。/proc/
pid/limits
允许您获取具有相同用户ID的任何进程的资源限制,并且在RHEL 5.2、RHEL 4.7、Ubuntu 9.04以及具有2.6.24或更高内核版本的任何发行版上都可用。getrlimit()
。当然,最简单的方法是修改程序或其使用的库。如果您正在运行该程序,则可以使用LD_PRELOAD
将自己的代码加载到程序中。如果这些都不可能,那么您可以使用gdb附加到进程并让它在进程内执行该调用。您还可以使用ptrace()
自己执行相同的操作,附加到进程,将调用插入其内存等,但这非常复杂且不建议使用。您可以尝试编写脚本,定期调用lsof -p {PID}
来查看给定pid的情况。
你需要bash/python方法的翻译。除了手动浏览/proc/$pid/fd
等文件外,ulimit是最好的bash方法。对于Python,您可以使用资源模块。
import resource
print(resource.getrlimit(resource.RLIMIT_NOFILE))
$ python test.py (1024, 65536)
resource.getrlimit
对应于 C 程序中的 getrlimit
调用。结果表示所请求资源的当前值和最大值。在上面的示例中,当前(软)限制为 1024。这些值是现代 Linux 系统上的典型默认值。
查看使用文件句柄最多的前20个进程:
for x in `ps -eF| awk '{ print $2 }'`;do echo `ls /proc/$x/fd 2> /dev/null | wc -l` $x `cat /proc/$x/cmdline 2> /dev/null`;done | sort -n -r | head -n 20
输出格式为文件句柄计数、进程ID、命令行。
示例输出:
701 1216 /sbin/rsyslogd-n-c5
169 11835 postgres: spaceuser spaceschema [local] idle
164 13621 postgres: spaceuser spaceschema [local] idle
161 13622 postgres: spaceuser spaceschema [local] idle
161 13618 postgres: spaceuser spaceschema [local] idle
import psutil
for p in psutil.process_iter(attrs=['pid', 'name', 'username', 'num_fds']):
try:
soft, hard = p.rlimit(psutil.RLIMIT_NOFILE)
cur = p.info['num_fds']
usage = int(cur / soft * 100)
print('{:>2d}% {}/{}/{}'.format(
usage,
p.info['pid'],
p.info['username'],
p.info['name'],
))
except psutil.NoSuchProcess:
pass