问题现象
系统正常启动之后运行一段时间再访问页面,部分页面会出现500错误页面。
说明:因为我们系统是TCP消息后台驱动运行的,所以会等一段时间在访问。
日志报错
问题排查及定位
- 看到报错时候,以为是报错的模块有问题,就去看代码排查,并未发现这个模块的问题,然后就把这个模块停用了,重启系统继续观察,发现问题并未消失,虽然不能说明本模块没问题,但是也说明了其他模块也有问题。
- 于是继续排查问题。使用到的命令如下
#查看用户级别可以打开的最大进程数
#root账号默认是cat /proc/sys/kernel/threads-max的值/2,即系统线程数的一半
#普通账号默认是cat /etc/security/limits.d/20-nproc.conf(centos6 是90-nproc.conf)
#ulimit -u==ulimit -a中的max_user_process
ulimit -u
ulimit -a
#--------------------------------------------------------------
#查系统支持的最大线程数
cat /proc/sys/kernel/threads-max
#--------------------------------------------------------------
#查系统最大pid
cat /proc/sys/kernel/pid_max
sysctl kernel.pid_max
#--------------------------------------------------------------
#用户运行最大线程数
cat /proc/sys/vm/max_map_count
#--------------------------------------------------------------
#默认的线程栈大小,单位是字节(Bytes)
ulimit -s==ulimit -a中的stack size
#--------------------------------------------------------------
#查询当前整个系统已用的线程或进程数
pstree -p | wc -l
#--------------------------------------------------------------
#查询当前某程序的线程或进程数
pstree -p ${pid} | wc -l
#--------------------------------------------------------------
#查看进程打开的每个文件
lsof -p ${pid}
#--------------------------------------------------------------
#查看进程打开的文件数
lsof -p ${pid} | wc -l
#根据pid进程把打开的文件数按照第九列排序(逆序)输出到openFiles.log文件中
lsof -p ${pid} |sort -k9 -r> openFiles.log
- 因为服务器是我们设置好的最大线程数是65535,所以线程数肯定是够用的。 既然不是设置问题,那就是代码的问题了。
继续排查,使用到的命令是查看进程打开的文件数lsof -p ${pid} | wc -l
,系统运行一段时间之后,再次查看,发现打开的文件数急剧增长。
继续排查,把打开文件的线程输出,使用命令根据pid进程把打开的文件数按照第九列排序(逆序)输出到openFiles.log文件中lsof -p ${pid} |sort -k9 -r> openFiles.log
把输出的文件传到本地打开,部分如下。因为不同系统导致打开文件过多的原因也不一样。所以我只根据自己的实际情况来说我的解决思路。
- 因为已经排序,所以很容易定位到哪个模块打开文件数多。
- pipe、eventpoll是netty的模块,我们系统多个模块使用到netty做的Tcp client和Tcp server。注释掉一个最有可能出现问题的模块,重启系统继续观察,发现一切正常。于是定位到是这个模块出现的问题,然后查看代码,确实有问题。因为本人对netty的了解程度一般般,就不详细介绍netty原因导致的打开文件数过多的解决方案。
解决方案
- 其实还有一种情况导致打开的文件过多报错,就是系统设置的最大线程太小了。修改系统相关参数请参考https://www.cnblogs.com/pangguoping/p/5792075.html
- 如果是项目打开文件不合理的原因,可以参考上面的解决思路,如有疑问请留言。