添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

一、故障说明

今天登录系统总是显示失败,查看日志的时候,发现日志中报出了大量的异常 Too many open files 。根据经验判断应该是操作了大量的文件并且在操作后,没有关闭文件流。

2022-03-29 22:22:47 [http-nio-8777-Acceptor] ERROR org.apache.tomcat.util.net.Acceptor : Socket accept failed
java.io.IOException: Too many open files
        at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
        at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:461)
        at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:73)
        at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:95)
        at java.lang.Thread.run(Thread.java:748)

二、too many open files描述

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

三、故障排除

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

[root@test]# 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) 1029324
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65536
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) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

open files那一行就代表系统目前允许单个进程打开的最大句柄数,这里是65536

因为我是用的是docker,里面仅仅启动了一个java程序。为此当我们使用top命令查看的时候,此处主要是为了获取程序的pid。

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
     1 root      20   0 7403544 807388  13820 S   1.7  0.3 100:29.02 java
 21267 root      20   0   15388   2112   1636 S   0.0  0.0   0:00.01 bash
 21283 root      20   0   59628   2124   1504 R   0.0  0.0   0:00.01 top
 

第一次操作lsof命令可能需要安装:yum install -y lsof

接下来看我这个java程序到底打开了多少文件。此处使用命令:lsof

lsof -p 1 |wc -l
# 返回值:65572

此时发现,进程1,也就是我们的java程序操作了65572个文件,并且没有关闭。超过了我们系统允许的数量65536。

如果是普通的虚拟机或者物理,可以通过如下命令,找到打开文件数量最多的进程:
#查看了排在前面的几个进程
lsof -n | awk '{print $2}' | sort | uniq -c | sort -nr | more

重新回到我们刚才的java 程序操作中,我们发现java程序的打开的文件太多了,我们将其操作的文件导出到文件中,在文件中查看。

lsof -p 1 > openfile.log

在导出的文件中找到打开次数最多的文件,然后在代码中排除即可。
我们的代码中是重复操作了同一个文件,文件名相同,比较好找,如果文件名字不同,可能需要开发人员细心排除一下了。

四、其他解决方案

如果故障原因不是因为文件没有关闭,或者项目需要开启更多句柄,可以修改配置文件,从而允许打开更多文件。

1、临时修改方案,重启失效。

# 将句柄设置为102048
ulimit -n 102048

2、永久方案

sudo vim /etc/security/limits.conf

文件的最后添加

*       soft    nofile  65535
*       hard    nofile  65535

最终效果:

#<domain>      <type>  <item>         <value>
#*               soft    core            0
#root            hard    core            100000
#*               hard    rss             10000
#@student        hard    nproc           20
#@faculty        soft    nproc           20
#@faculty        hard    nproc           50
#ftp             hard    nproc           0
#ftp             -       chroot          /ftp
#@student        -       maxlogins       4
*       soft    nofile  65535
*       hard    nofile  65535

最前的 * 表示所有用户,可根据需要设置某一用户
然后修改全系统总限制

sudo vim /etc/sysctl.conf

在文件底部添加:

fs.file-max=655350

立即生效:

sudo sysctl -p

这样就修改完毕了,用户级句柄数的修改需要重启一下才能生效,最好执行一下reboot,再次输入ulimit -n查看已经修改好了。

linux系统中对进程可以调用的文件句柄数进行了限制,超过限制进程将无法获取新的句柄,不能打开新的文件或者网络套接字,就会报错。 通过命令: lsof -p 进程id|wc -l :查询当前进程打开文件的数量 发现这个数量是在不断增加的,通过 lsof -p 进程id:查询当前进程打开的具体文件 TYPE类型为FIFO的文件在不断增
文章目录一、背景二、第一波排查1、 问题持续时间2、 错误日志3、tcp连接数4、 分析5、结论三、第二波排查1、分析2、结论3、解决四、参考文献 2020-03-23 08:10:07生产突然系统异常。 在系统重新之后恢复暂时恢复使用。一个比较诡异的错误,经过一番排查,最终才定位到问题代码,错误如下: 2020-03-20 08:10:07.039 [http-nio-80...
出现问题的原因: 1.可能是程序打开文件没有使用close()方法关闭打开的流,导致程序一直占用 2.可能是服务器允许每个用户打开文件的最大数量有限制(这种在文件使用关闭后,打开数量会降低) 针对第二种的处理方法: ps -ef|grep java 查看端口 lsof -p 端口 | wc -l 查看此端口打开的文件数量 ulimit -a 查看允许每个用户打开文件的最大数量 ulimit -n 4096 修改最大数量 ps:open files (-n) 1024这个参数就是系统默认允许用户打开文件最
记录一下通知平台mnp在客户环境的报错: 问题背景:客户端发送9007通知,mnp微服务处理通知状态正常的流程是:未报-->待报-->发送失败/发送成功,而本次实际上的结果是走到待报就结束了流程。 经排查发现日志有下图报错: 报错分析: java.io.IOException:Too many open files,IO异常,打开的文件数过多。原因是因为 操作系统的中打开文件的最大句柄数受限所致,常常发生在很多个并发用户访问服务器的时候.因为为了执行每个用户的应用服务器都要加载很多文
mac 版本charles安装报错-Charles cannot configure your proxy settings while it is on a read-only volume. read_act: 记录idea插件wl spring assistant plugin的坑-不提示配置项,显示黑树叶 去一次倒悬山: 我真是服了,刚开始是配置文件不提示,后面才发现压根就没被识别为spring配置文件,后来把这插件禁用了才行 雪花算法&改造16位或者15位 Stephen_Mao: 2^5=32,不是256 记录idea插件wl spring assistant plugin的坑-不提示配置项,显示黑树叶 aiming66: idea 默认安装的就支持提示,提供功能主要是springboot-start中的自动提示元数据,就在start依赖包META-INF中的spring-configuration-metadata.json或additional-spring-configuration-metadata.json。