脚本-检查Linux中给定进程的开放FD限制
我最近有一个Linux进程,它“泄漏”了文件描述符:它打开了文件描述符,但没有正确关闭其中的一些文件描述符。
如果我对此进行了监视,我可以提前告知-该过程已达到极限。
有没有一种不错的Bash \ Python方法来检查Ubuntu Linux系统中给定进程的FD使用率?
编辑:
我现在知道如何检查其中有多少个打开的文件描述符。 我只需要知道一个进程允许多少个文件描述符。 某些系统(例如Amazon EC2)没有/proc/pid/limits文件。
谢谢,
乌迪
7个解决方案
110 votes
计算/proc//fd/中的条目。在/proc//limits中可以找到适用于该过程的硬性限制和软性限制。
caf answered 2019-10-12T09:12:27Z
33 votes
Linux内核提供的唯一获得资源限制的接口是getrlimit()和getrlimit()pidLD_PRELOAD。 getrlimit()只能获取调用进程的资源限制。 2565804443048608608769pidptrace()允许您获取具有相同用户ID的任何进程的资源限制,并且在RHEL 5.2,RHEL 4.7,Ubuntu 9.04以及任何具有2.6.24或更高版本内核的发行版中可用。
如果您需要支持较早的Linux系统,则必须自己获取该过程以调用getrlimit()。当然,最简单的方法是修改程序或它使用的库。 如果您正在运行程序,则可以使用LD_PRELOAD将自己的代码加载到程序中。 如果这些都不可行,则可以使用gdb附加到进程,并使其在进程内执行调用。 您还可以使用ptrace()附加到进程,将调用插入其内存等操作来自己做同样的事情,但是这样做很复杂,不建议这样做。
如果拥有适当的特权,执行此操作的其他方法将涉及查看内核内存,加载内核模块或以其他方式修改内核,但是我假设这些都是不可能的。
mark4o answered 2019-10-12T09:13:08Z
2 votes
查看使用进程的前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
输出的格式为文件句柄计数,进程的pid,cmndline
示例输出
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
johnjamesmiller answered 2019-10-12T09:13:46Z
2 votes
您可以尝试编写脚本,该脚本会在给定的pid上定期调用lsof -p {PID}。
Victor Sorokin answered 2019-10-12T09:14:12Z
2 votes
您要求使用bash / python方法。 ulimit将是最好的bash方法(缺少手动操作getrlimit等)。 对于python,您可以使用资源模块。
import resource
print(resource.getrlimit(resource.RLIMIT_NOFILE))
getrlimit
getrlimit对应于C程序中的getrlimit调用。 结果代表所请求资源的当前值和最大值。 在上面的示例中,当前(软)限制为1024。这些值是当今Linux系统上的典型默认值。
bwalton answered 2019-10-12T09:14:52Z
0 votes
在CentOS 6和更低版本(使用GCC 3的任何版本)中,您可能会发现调整内核限制不能解决问题。 这是因为存在一个由GCC使用的在编译时设置的FD_SETSIZE值。 为此,您将需要增加该值,然后重新编译该过程。
另外,如果您正在使用该库,则可能会由于libpthread中的已知问题而泄漏文件描述符。 此调用已集成到GCC 4 / CentOS7 / RHEL 7中的GCC中,这似乎已解决了线程问题。
James Shewey answered 2019-10-12T09:15:25Z
0 votes
使用出色的psutil包的Python包装器:
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
Willem answered 2019-10-12T09:15:51Z