美文网首页Linux运维程序员Linux运维进阶-Python,Docker,Shell
[Linux] lsof的错误使用场景和查看打开文件数的正确方法

[Linux] lsof的错误使用场景和查看打开文件数的正确方法

作者: petergz | 来源:发表于2017-04-12 12:55 被阅读4348次

    [原创文章,转载请注明出处]

    前两天在调查一个"too many open files"的问题,和之前一样,自然而然的用到了lsof,加上一堆漂亮的命令组合来查看哪些程序打开了很多文件。
    lsof | awk '{print $2}' | uniq -c | sort -rnk1 | head
    啪的一敲回车,很顺利的定位到几个docker内运行的Java进程排在最前,分别都是几万的结果,怀疑是不是docker的问题。很不幸的是,这个调查结果是错的。。。

    先说真实的情况,后面再展开分析:

    • 真实的元凶,是一个并没有在上面的命令结果中排在最前面的进程,由于编程的bug,不断的打开同样的文件没有关闭,真正的占用了很多fd。
    • CentOS 7中的lsof是按PID/TID/file的组合显示结果的,上面lsof组合命令显示“打开”了很文件的进程,只是因为进程运行了N个线程,而每个线程都“用到”了M个jar包,并且FD一栏分别为mem和具体fd号都分别显示了一次,就出现了2*N*M——上万条结果。

    结论一:
    使用lsof查看fd数是不正确的。
    尽管网上很多文章教人这么用,但实际上不应该这么做。

    这是因为:

    1. lsof的结果包含了并非以fd形式打开的文件,比如用mmap方式访问文件(FD一栏显示为mem),实际并不占用fd。
      其中包括了像.so这样的文件。从结果看.jar文件也是以FD为mem和具体fd编号分别打开了一次。
    2. CentOS 7的lsof(我这里lsof -v的版本号是4.87)是按PID/TID/file的组合对应一行,不是一行一个fd。同一个进程如果多个线程访问同一个文件通常只需要打开一次、占用一个fd,但在lsof中就显示多行。
      如果用lsof -p <pid>,则不按TID显示,结果数少很多。但仍包含了没有使用fd的文件。

    结论二:
    准确的查看fd使用总数的命令是:
    cat /proc/sys/fs/file-nr
    或者(结果多的时候运行需要一段时间)
    sudo find /proc -print | grep -P '/proc/\d+/fd/'| wc -l

    注意如果用
    sudo ls -l /proc/*/fd/* | wc -l
    结果是不对的,比上面的命令返回结果少很多。原因是实际执行是会把*扩充成具体的目录作为参数,而这个参数长度有限制。

    查看具体一个进程号的fd数量是:
    ls -l /proc/<pid>/fd | wc -l

    查看哪个进程使用的fd最多(再来一路组合拳):
    sudo find /proc -print | grep -P '/proc/\d+/fd/'| awk -F '/' '{print $3}' | uniq -c | sort -rn | head

    但还要注意上面的命令返回的是系统的fd使用情况,而ulimit的配置是针对单用户的,两者是有区别的。

    结论三:
    不同版本的lsof输出结果不同。

    CentOS 7.3的lsof (我这里是4.87),按PID/TID/file显示。CentOS 6.6的lsof(我这里是4.82),按PID/file显示。结果数相差很大。但lsof -p <pid>的结果是一致的。
    这在容器OS版本和宿主机OS版本不同时就需要注意了,在容器里和宿主机上用lsof查看同一进程的结果会很不同,我碰到的就是这种情况。

    </br>


    之前使用lsof(或lsof -n不解析协议主机名)的相关命令和真实意义:
    打开文件总记录数(没太大意义):
    lsof | wc -l

    lsof -n | wc -l #不解析协议主机名

    查看哪些pid使用文件数量最多(其实也没有太大意义):
    lsof | awk '{print $2}' | uniq -c | sort -rnk1 | head

    相关文章

      网友评论

        本文标题:[Linux] lsof的错误使用场景和查看打开文件数的正确方法

        本文链接:https://www.haomeiwen.com/subject/gwjnottx.html