生产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

相关文章

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

redis群集简单部署过程

《redis群集简单部署过程》文章介绍了Redis,一个高性能的键值存储系统,其支持多种数据结构和命令,它还讨论了Redis的服务器端架构、数据存储和获取、协议和命令、高可用性方案、缓存机制以及监控和... 目录Redis介绍1. 基本概念2. 服务器端3. 存储和获取数据4. 协议和命令5. 高可用性6.

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2

在MySQL执行UPDATE语句时遇到的错误1175的解决方案

《在MySQL执行UPDATE语句时遇到的错误1175的解决方案》MySQL安全更新模式(SafeUpdateMode)限制了UPDATE和DELETE操作,要求使用WHERE子句时必须基于主键或索引... mysql 中遇到的 Error Code: 1175 是由于启用了 安全更新模式(Safe Upd

Python安装时常见报错以及解决方案

《Python安装时常见报错以及解决方案》:本文主要介绍在安装Python、配置环境变量、使用pip以及运行Python脚本时常见的错误及其解决方案,文中介绍的非常详细,需要的朋友可以参考下... 目录一、安装 python 时常见报错及解决方案(一)安装包下载失败(二)权限不足二、配置环境变量时常见报错及

springboot将lib和jar分离的操作方法

《springboot将lib和jar分离的操作方法》本文介绍了如何通过优化pom.xml配置来减小SpringBoot项目的jar包大小,主要通过使用spring-boot-maven-plugin... 遇到一个问题,就是每次maven package或者maven install后target中的ja

Java中八大包装类举例详解(通俗易懂)

《Java中八大包装类举例详解(通俗易懂)》:本文主要介绍Java中的包装类,包括它们的作用、特点、用途以及如何进行装箱和拆箱,包装类还提供了许多实用方法,如转换、获取基本类型值、比较和类型检测,... 目录一、包装类(Wrapper Class)1、简要介绍2、包装类特点3、包装类用途二、装箱和拆箱1、装

如何利用Java获取当天的开始和结束时间

《如何利用Java获取当天的开始和结束时间》:本文主要介绍如何使用Java8的LocalDate和LocalDateTime类获取指定日期的开始和结束时间,展示了如何通过这些类进行日期和时间的处... 目录前言1. Java日期时间API概述2. 获取当天的开始和结束时间代码解析运行结果3. 总结前言在J

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动