原创

Linux 中如何解决 too many open files 异常问题

产生原因

Linux系统中too many open files异常是比较常见的错误,从字面意思上看就是说程序打开的文件数过多,不过这里的files不单是文件的意思,也包括打开的通讯链接(比如socket),正在监听的端口等,所以有时又称为句柄(handle),这个错误通常可以叫做句柄数超出系统限制。例如如下错误信息:

Caused by: java.io.FileNotFoundException: /home/tomcat/jingxuan-tomcat/webapps/jingXuanAPI/WEB-INF/lib/activemq-client-5.9.1.jar (Too many open files)
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:225)
        at java.util.zip.ZipFile.<init>(ZipFile.java:155)

原因分析

进程在某个时刻打开了超过系统限制的文件数量以及通讯链接数,通过命令ulimit -a可以查看当前系统设置的最大句柄数是多少。

[root@mrwang ~]# ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 14429
max locked memory       (kbytes, -l) 16384
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 14429
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

其中“open files”参数表示系统目前允许单个进程打开的最大句柄数,这里是65535,该服务器已经调整过了,默认是1024。使用命令“lsof -p 进程id”可以查看单个进程所有打开的文件详情,使用命令“lsof -p 进程id | wc -l”可以统计进程打开了多少文件。

如果文件数过多使用“lsof -p 进程id”命令无法完全查看的话,可以使用“lsof -p 进程id > openfiles.log”将执行结果内容输出到日志文件中查看。

[root@mrwang ~]# lsof -p 8288
COMMAND  PID USER   FD   TYPE             DEVICE  SIZE/OFF      NODE NAME
java    8288 root  cwd    DIR              253,1       160   1717293 /home/tomcat/apache-tomcat-server
java    8288 root  rtd    DIR              253,1       244       128 /
java    8288 root  txt    REG              253,1      8712   1507063 /home/jdk/jdk1.8.0_291/bin/java
java    8288 root  mem    REG              253,1    168368  33739024 /usr/lib64/libresolv-2.28.so
java    8288 root  mem    REG              253,1     41304  33739018 /usr/lib64/libnss_dns-2.28.so
java    8288 root  mem    REG              253,1   3559360  67178238 /home/jdk/jdk1.8.0_291/jre/lib/resources.jar
java    8288 root  mem    REG              253,1    104256  34147343 /usr/lib64/libgcc_s-8-20190507.so.1
java    8288 root  mem    REG              253,1    283368  84407379 /home/jdk/jdk1.8.0_291/jre/lib/amd64/libsunec.so
java    8288 root  mem    REG              253,1    113008  84407389 /home/jdk/jdk1.8.0_291/jre/lib/amd64/libnet.so
java    8288 root  mem    REG              253,1     93872  84407404 /home/jdk/jdk1.8.0_291/jre/lib/amd64/libnio.so
...

解决方法

方式一:命令方式

ulimit -n 2048

命令的意思是把当前用户的最大允许打开文件数量设置为2048,注意这种设置方法在重启后会还原为默认值。 ulimit -n命令非root用户只能设置到4096,如果想要设置到更大需要sudo权限或者root用户。

方式二:修改系统配置文件

[root@mrwang ~]# vim /etc/security/limits.conf

在文件末尾处增加如下内容:

* soft nofile 4096  
* hard nofile 4096

或者

 * - nofile 8192

*表示所有用户,可根据需要设置某一用户,例如:

jingxuan soft nofile 8192  
jingxuan hard nofile 8192

注意的是“nofile”项有两个可能的限制措施,分别是hard和soft。要使修改过得最大打开文件数生效,必须对这两种限制进行设定。 如果使用”-“字符设定, 则hard和soft设定会同时被设定。

~阅读全文-人机检测~

关注下方微信公众号“Java精选”(w_z90110),回复关键词领取资料:如Mysql、Hadoop、Dubbo、Spring Boot等,免费领取视频教程、资料文档和项目源码。微信搜索小程序“Java精选面试题”,内涵3000+道Java面试题!

Java精选专注程序员推送一些Java开发知识,包括基础知识、各大流行框架(Mybatis、Spring、Spring Boot等)、大数据技术(Storm、Hadoop、MapReduce、Spark等)、数据库(Mysql、Oracle、NoSQL等)、算法与数据结构、面试专题、面试技巧经验、职业规划以及优质开源项目等。其中一部分由小编总结整理,另一部分来源于网络上优质资源,希望对大家的学习和工作有所帮助。

评论

分享:

支付宝

微信