zoukankan      html  css  js  c++  java
  • Linux中Too many open files 问题分析和解决

    今天某个服务的日志中出现了大量的异常:

    [WARN ] 2018-06-15 16:55:20,831 --New I/O server boss #1 ([id: 0x55007b59, /0.0.0.0:20880])-- [org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink] [DUBBO] Failed to accept a connection., dubbo version: 2.8.3.2, current host: 127.0.0.1
    java.io.IOException: Too many open files
    at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) ~[na:1.7.0_09-icedtea]
    at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:226) ~[na:1.7.0_09-icedtea]
    at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink$Boss.run(NioServerSocketPipelineSink.java:244) ~[netty-3.2.5.Final.jar:na]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [na:1.7.0_09-icedtea]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [na:1.7.0_09-icedtea]
    at java.lang.Thread.run(Thread.java:722) [na:1.7.0_09-icedtea]
    Too many open files这个问题主要指的是进程企图打开一个文件,或者叫句柄,但是现在进程打开的句柄已经达到了上限,已经无法打开新句柄了。

    网上一提到这个问题就要增加句柄上限,而往往这种情况的发生是因为错误的使用了句柄,可以称作句柄泄漏,找到句柄达到上限的原因才是王道。

    以下是Linux中句柄的介绍

    Linux中所有的事物或资源都是以文件的形式存在,比如消息、共享内存、连接等,句柄可以理解为指向这些文件的指针。

    对于这些句柄,Linux是有数量限制的,单个进程默认可以打开的句柄数上限,可以用以下命令来查看:

    ulimit –a
    执行结果如下:

     

    其中的open files一项就是默认的句柄数,此时默认的句柄数是1024

    还可以设置某个进程的句柄数上限,命令是:

    ulimit –a PID
    执行结果如下:

     

    也是看open files一项,可以看到,该进程的句柄上限也是1024

    这个句柄数是可以改的,修改默认的句柄数,命令如下:

    ulimit –n 2000
    这个命令可以把默认的句柄数改为2000,但系统重启后会恢复默认值

    这个文件在系统中的默认值配置在/etc/security/limits.conf文件中,加入以下配置:

    * soft nofile 2000
    * hard nofile 2000
    或者

    * - nofile 2000
    其中hard的设置是实际的默认值,也就是上限,而soft的配置只是用来警告的,如果超过了soft的值,会有warn,而第三种用短横线– 的配置,则是hard和soft同时配置的方式。

    下面看一下如何查询系统中进程占用的句柄数

    使用的命令是:

    lsof -n|awk '{print $2}'|sort|uniq -c|sort-nr|more
    lsof命令是Linux中的一个系统监视命令,可以查看进程打开的文件、端口等,功能强大,上面的命令通过一串的管道后只保留了句柄数和PID,执行结果如下:

    第一列是句柄数,第二列是进程id

    可以看到前两个进程的句柄数已经超过上限了,这正是这两个进程的日志正在报文章最上方的异常。

    下面查询某个进程都占用了一些什么样的句柄

    比如查询PID为25950的进程,使用的命令是

    lsof |grep 25950
    执行结果如下:

     

    这里是截取的一部分,每列的含义如下:

    1,进程名称

    2,PID

    3,进程所有者

    4,文件描述符

    5,文件类型

    文件类型有以下几种:

    DIR:表示目录。

    CHR:表示字符类型。

    BLK:块设备类型。

    UNIX: UNIX 域套接字。

    FIFO:先进先出 (FIFO) 队列。

    IPv4:网际协议 (IP) 套接字。

    DEVICE:指定磁盘的名称

    SIZE:文件的大小

    NODE:索引节点(文件在磁盘上的标识)

    NAME:打开文件的确切名称

    在我查看的这个进程中,有异常大量的IPv4类型文件被打开,以此为线索可以分析出具体的句柄超限的原因。在文章最开始的例子中,是因为程序不停的对另一台服务器发起连接,导致句柄超上限(从异常信息中其实也能分析出来)。
    ————————————————
    版权声明:本文为CSDN博主「lkforce」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/lkforce/article/details/80710459

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 一元三次方程
    Java实现 蓝桥杯VIP 算法训练 乘法表
    Java实现 蓝桥杯VIP 算法训练 矩阵加法
    Java实现 蓝桥杯VIP 算法训练 一元三次方程
    Java实现 蓝桥杯VIP 算法训练 平方计算
    Java实现 蓝桥杯VIP 算法训练 平方计算
    Java实现 蓝桥杯VIP 算法训练 平方计算
    Java实现 蓝桥杯VIP 算法训练 乘法表
    Java实现 蓝桥杯VIP 算法训练 乘法表
    监管只是压倒网盘业务的一根稻草,但不是主要原因(答案只有一个:成本!)
  • 原文地址:https://www.cnblogs.com/surplus/p/11746642.html
Copyright © 2011-2022 走看看