问题描述:
近日运维反馈我们项目组有两台sftp服务器句柄数过高,达到4.7万+,超过监控阈值4.5万。运维监控使用的命令如下:
cat /proc/sys/fs/file-nr
47008 0 6815744
原因分析:
我们常用的查询句柄的命令是lsof,结果与运维的命令相差很大(两种命令都需要root用户执行)。lsof结果如下:
lsof | wc -l
80311
查阅了部分资料,发现两个命令有一定关联,具体可以参考这两个博客:
附上lsof命令结果详解:
lsof命令_Linux系统lsof命令详解
综合来讲,就是file-nr统计的是fd,即真正的文件句柄。lsof的结果包含了并非以fd形式打开的文件,比如用mmap方式访问文件(fd一栏显示为mem),实际并不占用fd。其中包括了像.so和.jar文件,也是以fd为mem和具体fd编号分别打开了一次。
虽然lsof的结果并不是真的句柄数,但是除去非fd形式的数量也能间接反映是什么原因导致的。因为服务器专门的sftp服务器,没有部署其他应用,所以我们需要知道每个用户占用了多少句柄数,于是再执行以下命令查看(结果中包含非fd的数量):
lsof -n | awk '{print $3}' | sort | uniq -c | sort -nr | head -4
46125 sftpuser1
33144 root
369 sftpuser2
369 sftpuser3
从结果可以看出,居然有用户比root使用的句柄数(结果均包含非fd的数量)还高,那大概率是这个用户连接sftp未释放导致的。
解决方案:
于是查看该用户连接sftp的代码,确实发现了有一处没有关闭链接,日积月累下来,则超过了告警阈值。
临时方案:重启对应的应用服务。重启后句柄数已经降下来了,执行命令:
cat /proc/sys/fs/file-nr
2080 0 6815744
最终方案:修改代码。。。
总结:
从这次事件来看,码农的任何一个不注意的点在日积月累后都可能造成蝴蝶效应,所以平时开发中还是要注重代码的质量,否则说不准哪天因为左脚先进办公室就被炒鱿鱼了。