生产java.io.IOException: Too many open files排查过程和解决方案

2024-06-08 18:58

本文主要是介绍生产java.io.IOException: Too many open files排查过程和解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 一、背景
    • 二、第一波排查
        • 1、问题持续时间
        • 2、错误日志
        • 3、tcp连接数
        • 4、句柄打开数
        • 5、 分析
        • 6、结论
    • 三、第二波排查
        • 1、分析
        • 2、结论
        • 3、解决
    • 四、参考文献

一、背景

2020-03-23 08:10:07生产突然系统异常。
在系统重新之后恢复暂时恢复使用。一个比较诡异的错误,经过一番排查,最终才定位到问题代码,错误如下:

2020-03-20 08:10:07.039 [http-nio-8050-Acceptor-0] ERROR org.apache.tomcat.util.net.Acceptor - Socket accept failed
java.io.IOException: Too many open filesat 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:446)at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:70)at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:95)at java.lang.Thread.run(Thread.java:748)

二、第一波排查

1、问题持续时间

8:10 - 8:25

2、错误日志

第一次出现错误是在

2020-03-20 08:10:07.039 ITGC [http-nio-8050-Acceptor-0] ERROR org.apache.tomcat.util.net.Acceptor - Socket accept failed
java.io.IOException: Too many open files

在这里插入图片描述

3、tcp连接数

8:10:07的时候tcp连接数也是不多的,在200左右非常小,已经过了访问高峰

netstat -nat|grep -i "8050"|wc -l2020-03-20 08:10:05
169
2020-03-20 08:10:07
177
2020-03-20 08:10:09
184
2020-03-20 08:10:11
188
2020-03-20 08:10:13
199
4、句柄打开数

对于打开的句柄发现大量未成功释放的文件

查看进程打开的资源情况
ls -l /proc/13544/fd/
发现有大量tmpip.db未释放
查看进程打开的tmpip.db 的数量
ls -l /proc/13544/fd/ | grep tmpip.db |wc -l
ls -l /proc/13544/fd/ | grep tmpip.db 

在这里插入图片描述
附上:
查看进程打卡的各个资源数量排序前八位

lsof -p 13544 |awk '{print $9}'| sort|uniq -c |sort -nr | head -n 8
5、 分析

目前除了重启应用解决外,具体原因还未确认

1、当时的打卡人数每分钟不超过20人。

2、对于tcp连接是有记录实时日志的,连接数不到200。

3、对于当前打开文件数量是没有记录的。13544是进程pid,可以 ps -ef |grep java 查看或者直接 jps 查看。

ls -l /proc/13544/fd/  | wc -l 

4、Linux的文件句柄数设置是正常的。ulimit –n 是65534
5、根据上面步骤4,看得出有大量未释放的。

6、结论

因为持续了很多天没有发布重启过应用,在累计几周的情况下。应用突然崩溃。

1、打开的文件数没有做日志记录。在文件打开关闭有问题上面不排除有异常,因为lsof查看到每天有打开/tmpip.db文件但是一直未正确关闭,导致累计。

2、属于累计达到一定量之后崩溃的系统,那么在jvm上面也不排除有堆栈异常导致。

3、其他异常也正在排查

三、第二波排查

1、分析

根据以上结论进行第二波:
首先针对最多未释放的资源tmpip.db进行排查,因为代码里面日志记录代码有使用该文件。每次打卡都会插入日志,日志里面记录ip地址解析对应的中文地址会使用 tmpip.db,接着进行排查。

查看每个用户允许打开的最大文件数 ulimit -a 或者 ulimit -n 查看
open files (-n) 65534


65534
[root@CN07ATT01NGX01V ~]#  ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 14996
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65534  
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) 14996
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimitedopen files       (-n) 65534

查看系统允许打开的最大文件数 cat /proc/sys/fs/file-max

root@CN07ATT01NGX01V ~]# cat /proc/sys/fs/file-max
379184
[root@CN07ATT01NGX01V ~]# 

基于这个问题是日积月累之后突然爆发的,于是对比中午打卡和下午打卡人数和未释放的文件句柄数对比,发现基本是能对应的上的。

截止2020-03-20 19:24分

中午打卡日志数量 334条
下午打卡日志数量 530条
中午打卡后
[root@CN07ATT01NGX01V ~]# ls -l /proc/13544/fd/ | wc -l
835
下午打卡后
[root@CN07ATT01NGX01V ~]# ls -l /proc/13544/fd/ | wc -l
1368

相差1368-835=533

可见,未释放的资源几乎是和打卡日志相同数量递增的,
接着从今天出现问题前的最后一次启动,到今天出现问题时候启动时间段内,把日志做了一次查询统计:

select count(1) from t_log where  create_time>"2020-03-03 21:29:00" and create_time<="2020-03-20 08:10:07"  order by create_time desc

在这里插入图片描述

如上图,启动后一共产生打卡日志64001条。

每个用户允许打开的最大文件数65534

差额为65534-64001 =1533个文件打开数。

2、结论

因此结论一时正确的,附上具体结论内容:

[root@CN07ATT01NGX01V ~]# ls -l /proc/13544/fd

/tmpip.db的资源占用未及时释放导致系统的文件句柄数量越来越大。在今天超出。报异常

java.io.IOException: Too many open files

3、解决

1、日志方法记录ip的时候调用了AddressUtil的getCityInfo(String ip)
根据传入去得到对应的中文地址,内部逻辑使用了tmpip.db。因此针对这部分代码进行核查。看是否有未释放,果然对于dbsearch使用之后是没有释放的,于是添加dbSearch.close方法进行关闭资源。
在这里插入图片描述
2、在代码修改前,我们先在测试系统也还原到了这个问题,添加释放方法之后,资源释放问题得以解决!

四、参考文献

java.io.IOException: Too many open files问题常用命令https://blog.csdn.net/liyuguanguan/article/details/90716709
对于高并发的产生:java.io.IOException: Too many open files(打开文件句柄过多问题)
https://my.oschina.net/czpdjx/blog/2980869
java.io.IOException: Too many open files问题
https://blog.csdn.net/liyuguanguan/article/details/90716709
linux进程数和句柄数
https://blog.csdn.net/Poetic_Vienna/article/details/87621371?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

这篇关于生产java.io.IOException: Too many open files排查过程和解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1043032

相关文章

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

java中反射Reflection的4个作用详解

《java中反射Reflection的4个作用详解》反射Reflection是Java等编程语言中的一个重要特性,它允许程序在运行时进行自我检查和对内部成员(如字段、方法、类等)的操作,本文将详细介绍... 目录作用1、在运行时判断任意一个对象所属的类作用2、在运行时构造任意一个类的对象作用3、在运行时判断

java如何解压zip压缩包

《java如何解压zip压缩包》:本文主要介绍java如何解压zip压缩包问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解压zip压缩包实例代码结果如下总结java解压zip压缩包坐在旁边的小伙伴问我怎么用 java 将服务器上的压缩文件解压出来,

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

Spring事务传播机制最佳实践

《Spring事务传播机制最佳实践》Spring的事务传播机制为我们提供了优雅的解决方案,本文将带您深入理解这一机制,掌握不同场景下的最佳实践,感兴趣的朋友一起看看吧... 目录1. 什么是事务传播行为2. Spring支持的七种事务传播行为2.1 REQUIRED(默认)2.2 SUPPORTS2

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.