首页 > 基础资料 博客日记
java.io.IOException: Too many open files 分析与解决
2024-10-21 07:00:06基础资料围观83次
一 问题背景:
近日有个运营了几个月的新项目,客户方告知充电桩设备断开后无法再重连接服务器,之前是的正常,于是检查 接入的前置服务器项目日记,发现项目日记最近几天在量报错java.io.IOException: Too many open files ,如下图:
项目日记时不时会报错
二 分析具体原因:
开发网络应用时遇到 java.io.IOException: Too many open files
错误,这意味着你的应用程序尝试打开的文件描述符数量超过了系统允许的最大数量。在 Linux 中,每个进程可以打开的文件描述符的数量是有限制的。
1 文件描述符列表:
1 标准文件描述符:
- stdin:标准输入,默认指向键盘。
- stdout:标准输出,默认指向终端。
- stderr:标准错误输出,默认指向终端。
2 普通文件:
- 打开的普通文件,如文本文件、二进制文件等。
3 目录:
- 打开的目录。
4 设备文件:
- 如块设备文件(block devices)和字符设备文件(character devices)。
5 网络套接字(重点):
- 包括 TCP、UDP 等类型的套接字。
- 例如,一个 HTTP 服务器可能会打开多个 TCP 套接字来处理客户端请求。
6 命名管道(FIFO):
- 用于进程间通信的一种机制。
7 匿名管道:
- 用于父子进程间的通信。
8 共享内存对象:
- 用于进程间共享数据。
9 信号量:
- 用于进程间同步。
10 定时器:
- 用于实现定时功能。
11 事件文件描述符:
- 如 inotify 文件描述符,用于监视文件系统事件。
12 Unix 域套接字:
- 用于同一主机上的进程间通信
2 查看进程打开的文件描述符数量
使用以下命令来查看某个 Java 进程当前打开的文件描述符数量:
1 找到 Java 进程的 PID:
你可以使用 ps aux | grep java
来查找进程的 PID。
ps aux | grep 应用名称
2 查看打开的文件描述符:
找到进程的 PID 后,可以使用 lsof
命令来查看该进程打开的文件描述符数量:
lsof -p <PID> | wc -l
lsof 指令在统计比较多的网络符时会非常慢,可以改用以下指令:
ls -1 /proc/进程id号/fd | wc -l
这将返回一个近似的文件描述符数量,通常这个方法比 lsof
更快。
操作结果 如下图:
注意:由于当时急着修改问题没有截图,修复后补的图,如果是修复前应该不超系统限制的1024。
3 详细分析原因:
当前项目是用来接收充电桩报文的前置服务器,每台充电桩占用一个TCP连接,即1个连接也就是1个文件描述符,项目上线已有几个月,随着业务的增加,充电桩的数量也相应增加,当前的充电桩从原有的100多台慢慢增加到一千多台,也就是说单单连接就占用1000多个文件描述符,加上就用本身的一些如进程通信定时器,文件日记等等的文件描述符,也就超过1024,所以产生了些错误。在修复后,为了明确应用占用了多少文件符,我们再次查看该应用发现有1627个文件描述符。
三 解决方案:
1 增加限制
如果需要临时增加限制,可以在命令行中执行:
1ulimit -n 65536
执行后如下图:
2 永久修改限制
若要永久性地改变文件描述符限制,需要编辑 /etc/security/limits.conf
文件,添加如下行:
1* soft nofile 65536
2* hard nofile 65536
这里的 *
表示所有用户,也可以替换为特定用户名或用户组,如替换成root管理员。soft
和 hard
分别代表了可以由用户更改的限制和管理员才能更改的上限。
编辑 /etc/security/limits.conf
文件操作如下图:
3 查看当前限制
可以通过下面的命令来查看当前用户的文件描述符限制:
1ulimit -n
操作后如下图:
小结:
在linux系统中一般涉及网络多设备接入基本都要配置系统的打开文件符号数,当设备连接超过600时,默认的1024是可能不够用的,不要忘记要养成好习惯。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: