前几天发现服务器上的一个JAVA程序表现很不对劲,运行起来特别“慢”,仔细一看程序的日志,发现里面有Exception抛出,提示“too many open files”,由于无论是读写文件还是创建网络连接,都需要占用文件描述符(fd),于是怀疑是服务器上的某个程序占用的资源没有释放,达到了系统设置的上限从而导致程序异常。
『1』查看系统open files限制
可以用下面的命令来查看:
『1』查看系统open files限制
可以用下面的命令来查看:
ulimit -n
文章来源:https://www.codelast.com/
『2』查看系统里占用fd最多的进程
用root用户运行下面的命令,可以打印出每个进程占用的fd数量(从大到小):
lsof -n | awk '{print $2}' | sort | uniq -c | sort -nr | more
部分输出类似于:
12520 16485125 705469 2012069 1529165 2011365 1528457 19774......
第一列是占用的fd数量,第二列是进程的pid。最可疑的显然是占用数量最多的头几个进程。
ll /proc/16485/fd
部分输出类似于:
lrwx------ 1 root root 64 Aug 24 11:51 9992 -> socket:[547491750]lrwx------ 1 root root 64 Aug 24 11:51 9993 -> socket:[547491752]lrwx------ 1 root root 64 Aug 24 11:51 9994 -> socket:[547491753]lrwx------ 1 root root 64 Aug 24 11:51 9995 -> socket:[547491754]lrwx------ 1 root root 64 Aug 24 11:51 9996 -> socket:[547491755]lrwx------ 1 root root 64 Aug 24 11:51 9997 -> socket:[547491756]lrwx------ 1 root root 64 Aug 24 11:51 9998 -> socket:[547491757]lrwx------ 1 root root 64 Aug 24 11:51 9999 -> socket:[547491758]
其实这个输出列表真的很长,只不过由于篇幅的原因,这里只粘贴上来了一小部分。从这个输出信息中,貌似一眼看不出来该程序占用的那些fd到底是在进行网络通信呢,还是在干嘛,于是我们可以用另一种方法:
lsof -p 16485
还是只展示一小部分输出信息:
java 16485 root *500u IPv4 547501909 0t0 TCP abc.abc.com:57700->test1.abc.com:50010 (CLOSE_WAIT)java 16485 root *501u IPv4 547501910 0t0 TCP abc.abc.com:targus-getdata->test2.abc.com:50010 (CLOSE_WAIT)java 16485 root *502u IPv4 547501911 0t0 TCP abc.abc.com:59671->test3.abc.com:50010 (CLOSE_WAIT)java 16485 root *503u IPv4 547501939 0t0 TCP abc.abc.com:55784->test4.abc.com:50010 (CLOSE_WAIT)java 16485 root *504u IPv4 547501942 0t0 TCP abc.abc.com:netsupport->test5.abc.com:50010 (CLOSE_WAIT)java 16485 root *505u IPv4 547501995 0t0 TCP abc.abc.com:58486->test6.abc.com:50010 (CLOSE_WAIT)java 16485 root *506u IPv4 547501996 0t0 TCP abc.abc.com:38031->test7.abc.com:50010 (CLOSE_WAIT)
由于我这里的test*.abc.com是Hadoop集群的服务器,于是我马上就明白了:我的程序里有读写HDFS文件的操作,所以很可能是读写时没有close资源导致占用的fd持续增加。
于是我去检查了一下代码,果然在用BufferedReader频繁读取HDFS文件的时候,用完了也没有把它close(),于是fix之后赶紧试验了一下,问题解决!
于是我去检查了一下代码,果然在用BufferedReader频繁读取HDFS文件的时候,用完了也没有把它close(),于是fix之后赶紧试验了一下,问题解决!
文章来源:https://www.codelast.com/
➤➤ 版权声明 ➤➤
转载需注明出处:codelast.com
感谢关注我的微信公众号(微信扫一扫):