socket fd泄露导致进程无法读写文件、进行网络请求问题排查


现象:一个后台进程在跑了1000多分钟后,不再写日志,同时进程还有每分钟发送的一个网络请求,在服务端也没看到日志。

排查方式:首先怀疑是进程hang住了,但是通过gdb attach到进程,再打断点到网络请求函数,发现仍然是正常的每分钟进入一次,但是会报server connect failed错误。说明进程仍在正常执行,只是写日志和网络请求都是失败了。

因此怀疑是进程的fd满了。用ps命令查看进程id,然后执行ll /proc/12260/fd打印进程的fd信息,发现socket数量达到了1006多个,再加上一些管道,刚好是1024个。

再用ulimit -a查看系统的进程最大fd数open files的值,正好为1024,说明是因为进程的fd满了,导致写日志和发送网络请求都失败了。

接下来就是排查出现fd泄露的位置。通过lsof -p 12260查看进程占用socket fd的类型,发现是UDP类型。在程序中,创建UDP套接字的只有一个位置,是通过socket+ioctl获取本机ip的函数,确认了该函数确实没有close掉fd,并且该函数也是一分钟调用一次。

结论:系统设置了进程最大的fd数量,创建socket会消耗fd,并且当fd到达最大值时无法再创建。使用linux原生的socket函数时需要记得close fd,否则会出现fd泄露问题。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM