“爱提踢斯”项目最近遇到一个问题,当FTP服务器磁盘没有空间时,设备会不断复位——这是测试人员反馈的。我们拿到log后,看到一个通信所用的文件打开失败。不断打印Too many open file,然后超时设备复位。同时我们看到数据库文件打开失败,无法写入数据。一个现象,看到好几处问题。还是从最初的表现来入手。虽然把bug指派给别人,但从时间、进度上考虑,周末还是去加班。而最后,解决了问题。根据老夫目测,是FTP的socket未关闭引起的。
# cat /proc/17835/limits | grep "files" Max open files 1024 4096 files
和系统默认值一样。查看已占用值:
1 2
# ll /proc/17835/fd | wc -l 1027
我们看到,已经占用上千个句柄,一直未释放。当达到系统最大值时,就会报Too many open files的错误。 匆匆已然四载,不曾想到,当年刚入职搞FTP的我,竟然会埋下地雷,让今天的我不幸踩中。在没有离职情况下,只好义无反顾地去解决bug。——而这个bug,正是因为未关闭socket造成的。 FTP客户端的实现,是需要打开2个socket的,一个是命令通道,一个是数据通道。在服务器没有磁盘空间情况下,write数据是返回错误的,使用FTP模块者认为是无法登陆,下次会再次尝试登陆——在这种情况下,登陆是正常的,只是无法写数据。但每次登陆,都会创建命令通道的socket,这导致了socket的泄漏,不会关闭,因为使用者并没有调用logout函数退出登陆。另一个问题是最主要的,每次写数据时,要创建数据通道的socket,但在出错时,并没有关闭数据通道的socket,而是直接返回。这再次导致了socket泄漏。找到了原因,解决起来就好办了。 自从知道可以查看某个进程占用的文件句柄,我去看看以前的设备,发现有个别文件占用句柄较多——也就几十个。目测是只打开但未关闭。出于热心,我把情况在部门群里说了,至于后续的事,因为那些不是我的职责范围,不敢越趄代庖。