Linux系统中的进程都会打开一定数量的句柄,如果所打开的句柄超过了限制,则会导致之后的申请失败。
使用以下命令可以查看进程的句柄数软上限:
ulimit -n
更为详细的信息可以查看/etc/security/limits.conf,其中如下内容即为单一进程能打开最大句柄数的硬限制和软限制:
* hard nofile 32768
* soft nofile 4096
可以直接修改此文件,保存即生效。一般句柄数达到上限可以看看是不是需要调大数字了。
查看系统中所有打开的文件可以使用lsof命令,运行的时候别忘了在root权限下。
简单介绍一下这个命令一些常用用法。
lsof /dev/null:列出文件/dev/null的打开情况;
lsof +d /dev/:列出目录/dev/下文件的打开情况;
lsof -u root:列出root相关进程的文件打开情况;
lsof -n:对网络文件不进行IP地址到主机名的解析,这将加快速度。
更多的信息可以通过man查看。
使用如下命令可以按句柄数由高到低列出所有进程:
lsof -n | awk
'NR>1{printf("%8d%16s%16s\n",
$2, $3, $1)}' | sort | uniq -c | sort -k1nr -k3,4 -k2n
命令中格式和排序调整只是个人喜好。
我们将发现很多句柄数为3的进程,这个3代表的是标准输入文件、标准输出文件和标准错误输出文件。有时候需要对句柄数算得比较精确,别忘了默认的这3个。
对于分析句柄数达到上限的问题只需要关注那些使用句柄数多的进程,因此加上一条限制,比如只显示句柄数大于100的进程:
lsof -n | awk
'NR>1{printf("%8d%16s%16s\n",
$2, $3, $1)}' | sort | uniq -c | awk '$1>100' | sort
-k1nr -k3,4 -k2n
将这条命令加入crontab,定时将使用句柄数较大的进程输出到某个文件,通过实时分析这些信息,可以进行预警。甚至可以分析某一进程的句柄数趋势,而判断这一进程是否存在句柄泄漏,简单来说,一个进程的句柄数只增不减,那肯定就有问题了,很可能打开文件后没有关闭。
以下是一个crontab中可能的具体例子,需要注意的是“%”可是需要转义的。
*/5 * * * * cd /root/scripts/log/
&& date
>> handle.log
&& /usr/sbin/lsof -n | awk
'NR>1{printf("\%8d\%16s\%16s\n",
$2, $3, $1)}' | sort | uniq -c | awk '$1>100' | sort
-k1nr -k3,4 -k2n >> handle.log
2>&1