Too many open files杂谈

一  文件描述符和文件句柄

①  linux一切皆文件

1) linux系统设计里面遵循'一切都是文件'的原则

2) 即: 磁盘文件、目录、'网络套接字(socket)'、磁盘、'管道(pipe)',所有这些都是'文件'

3)在我们打开'文件'的时候会返回一个'fd',即是'文件句柄'

②  文件句柄泄漏

1) 文件句柄泄漏,也叫'文件描述符泄漏'

2) 当我们'打开一个文件',操作系统就会给程序'分配'一个文件描述符

3) 如果在'使用完'成之后,'没有及时的关闭文件',就会造成文件句柄泄漏的问题

遗留: 什么'原因'导致没有及时关闭文件? '表象'是什么?

③  Too many open files报错解读

1) '错误通'常也可以叫做句柄数'超出'系统限制

"Too manay open files" 问题很'明显',文件描述符超出限制导致'无法打开'文件或创建网络连接
​
表象: 句柄数'不足'导致业务进程'无法打开更多'的文件进而导致进程启动失败

2) 思考: 超出的'原因'?

  [1]、初始设置的'小',导致'超限'

  [2]、'句柄'泄露,导致'异常'增加,超限  --> "分析是难点"

3) 常见现象

  [1]、如果'频繁'的打开文件,但是没有'close'关闭文件流

  [2]、打开'网络套接字(socket)'而'忘记释放'就会有句柄泄露的现象

④   相关内核参数 sysctl

1) 系统'最大打开'文件描述符数:/proc/sys/fs/file-max

备注: 是系统所有'用户'所有'进程'所允许打开的'上限'

2) 临时修改'方式1'

echo 6000000 > /proc/sys/fs/file-max

3) 临时修改'方式2'

sysctl -w fs.file-max = 6000000

4) '永久'生效 -->在/etc/sysctl.conf中设置

fs.file-max = 6000000

+++++++++++++++++++  "分割线"  +++++++++++++++++++

/proc/sys/fs/file-nr  --> 表示当前时刻'整个系统内核的文件句柄'统计数据,'只读的'

⑤  /etc/security/limits.conf  解读

* - nofile 65536 

  1) '*'表示: 所有的'用户'限制都一样,可指定'某个用户';'单个进程'可以打开的最大文件句柄数

  2) '-'表示: soft和hard

备注: nproc表示'单个用户'创建的'进程数'
​
nofile 值大于内核设置的 fs.nr_open 参数值导致登录系统'云服务器'失败

nofile和noproc 

⑥  lsof相关命令

lsof -n | awk '{print $2}' | sort | uniq -c | sort -nr | head -n 20

lsof -i :port         --> 查看'占用port'的进程

lsof -c 进程名         --> 列出进程所打开的文件

lsof -p pid           --> 获取的是当前'pid进程'文件句柄数

lsof -u user | wc -l  --> 查看当前用户总共打开'多少'文件,确定'是否'超限

lsof:WARNING:can't stat() fuse.gvfsd-fuse file system

lsof的错误使用场景和查看打开文件数的正确方法

⑦  ulimit命令

ulimit -a             --> 常看'所有'配置

ulimit -n             --> 查询当前用户'open files'的上限值

备注: 系统'默认'对文件句柄是有限制,不可能'让进程'无限制的调用句柄

ulimit -n 60000       --> 历临时'设置'当前用户的

ulimit – HSn 60000    --> 'soft'和'hard'设置相同   

⑧  Java常见的报错

1)  java.io.IOException: Too many open files

原因: 操作了'大量的文件',并且在操作后'没有关闭'文件流

2)  java.net.SocketException: Too many open files

原因: 建立socket连接时,由于最大句柄数受限,'没有可用的'文件句柄导致报错

详细解读:

   [1]、linux在'默认'情况下每个进程可以调用的最大句柄数是1024个

   [2]、如果超过了这个限制,进程将'无法获'取新的句柄

   [3]、而从导致不能打开新的文件或者'网络套接字',对于线上服务器即会出现服务'被拒绝'的情况

3) 报错一般体现在'业务'日志和/var/log/messages等'系统'日志

创建一个关于TCP的socket会获取一个socket文件的句柄

检查程序问题

Java文件句柄泄露排查

⑨  排查思路

1) 查看pid

ps -ef | grep program

2) 根据'pid'查看进程'打开'的文件数

ll /proc/pid/fd | wc -l

lsof -p pid | wc -l

目的: 确定当前进程打开的文件数是否'超过'系统上限

3) 查询进程'具体'打开了哪些文件

ll /proc/pid/fd > open.log

lsof -p pid > open.log

目的: 辅助查找'异常代码'的文件

⑩  相关参考

netstat -n | \

awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

"too many open files"的原理和解决方案

java.io.IOException: Too many open files

java.net.SocketException: Too many open files

java.io.IOException: Too many open files问题

nofile 值大于内核设置的 fs.nr_open 参数值导致登录系统'云服务器'失败

记一次文件句柄大量占用(泄露)排查

/proc/$pid/fd 展示的socket的inode号

How to Fix "java.io.FileNotFoundException Too many open files" Error

实战案例分享

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要解决"too many open files"的问题,可以从两个方面入手:修改系统配置和从程序层面解决。 首先,我们可以尝试修改系统的配置信息。根据引用所述,Linux系统维护了一个open files table来记录当前打开的文件信息,这个表有一个最大容量限制。如果超过这个限制,系统会拒绝其他文件操作并报错"Too many open files"。因此,我们可以通过修改系统配置来增加open files table的容量。 具体来说,可以通过修改Linux系统的文件描述符限制来提高open files table的容量。可以使用命令ulimit来查看和修改文件描述符限制。首先,使用ulimit -n命令查看当前文件描述符的限制。然后,根据实际需求,可以使用ulimit -n <new_limit>命令将文件描述符限制设置为一个较大的值。 除了修改系统配置,我们还可以从程序层面解决这个问题。引用提到,要复现这个问题通常需要一定的业务量和运行一段时间,才能达到系统的阈值。因此,我们可以通过优化程序的资源管理来避免打开过多的文件。 可以尝试以下几种方法来解决这个问题: 1. 确保在程序中正确关闭所有打开的文件。在程序运行结束或不再需要打开的文件时,及时关闭文件。 2. 使用文件池或缓存来管理文件的打开和关闭。通过维护一个固定大小的文件池,在需要访问文件时,从池中获取可用的文件句柄,使用完毕后将文件句柄放回池中。 3. 优化程序的资源使用。检查程序中是否存在资源泄漏或重复打开文件的情况,及时释放不再使用的资源。 综上所述,要解决"too many open files"的问题,可以通过修改系统配置来增加open files table的容量,以及从程序层面优化资源管理来避免打开过多的文件。这样可以提高系统的稳定性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值