一、文件句柄是什么?
对象在内存中是经常来回移动的,如何快速定位找到这个对象呢?
句柄说: “我来帮你找”
windows系统给出的方案
1.进程创建时,windows系统为进程构造了一个句柄表
2.当该进程希望获得一个内核对象句柄或者创建一个内核对象从而获得该对象句柄时
3.系统会将在句柄表中增加一个表项,表项的内容中存储了指向目标内核对象的指针
4.同时,系统返回这个表项在句柄表中的索引作为句柄。
联系:句柄表--户口本
二、文件句柄的本质
唯一标识符 (eg:身份证号)
三、线上问题概述
错误: Socket/File : too many open files(打开的文件过多)
这里的files不单是文件的意思,也包括打开的通讯链接(比如socket),正在监听的端口等等,所以有时候也可以叫做句柄(handle)
四、解决方案
-
方案 – 增加系统最大连接数
1.临时(重启后失效):
ulimit -n 4096(非root用户限制到4096)
2.永久生效(需要重启)
vim /etc/security/limits.conf
#在最后加入
* soft nofile 4096
* hard nofile 4096
-
根源上解决--检查程序问题:
lsof -p 进程id > openfiles.log 查看句柄全部详情
1)打开的这些文件是不是都是必要的?
2)定位到打开这些文件的代码
3)是否程序操作了文件写入,但是没有进行正常关闭
4)是否程序进行了通讯,但是没有正常关闭(也就是没有超时结束的机制) --(eg:post.releaseConnection()关闭连接)
延伸
代码中只用post.releaseConnection()关闭连接,经过再网上查找资料,说这种关闭并没有真正关闭连接,而是将该连接提交给 MultiThreadedHttpConnectionManager,等待复用。
Close_wate需要延迟几秒钟才能关闭连接,而每个Socket连接都需要等待几秒钟,压力过大时,开启的Socket连接超过了系统所能承受的最大连接数(ulimit -u 1024),所以抛出Too many open files异常。