概要:
linux系统默认open files数目为1024, 有时应用程序会报Too many open files的错误,是因为open files 数目不够。这就需要修改ulimit和file-max。特别是提供大量静态文件访问的web服务器,缓存服务器(如squid), 更要注意这个问题。
网上的教程,都只是简单说明要如何设置ulimit和file-max, 但这两者之间的关系差别,并没有仔细说明。
说明:
1. file-max的含义。man proc,可得到file-max的描述:
/proc/sys/fs/file-max
This file defines a system-wide limit on the number of open files for all processes. (See
also setrlimit(2), which can be used by a process to set the per-process limit,
RLIMIT_NOFILE, on the number of files it may open.) If you get lots of error messages
about running out of file handles, try increasing this value:
即file-max是设置 系统所有进程一共可以打开的文件数量 。同时一些程序可以通过setrlimit调用,设置每个进程的限制。如果得到大量使用完文件句柄的错误信息,是应该增加这个值。
也就是说,这项参数是系统级别的。
2. ulimit
Provides control over the resources available to the shell and to processes started by it, on systems that allow such control.
即设置当前shell以及由它启动的进程的资源限制。
显然,对服务器来说,file-max, ulimit都需要设置,否则就可能出现文件描述符用尽的问题
修改:
1.修改file-max
# echo 6553560 > /proc/sys/fs/file-max //sysctl -w "fs.file-max=34166",前面2种重启机器后会恢复为默认值
vim /etc/sysctl.conf, 加入以下内容,重启生效
fs.file-max = 6553560
2.修改ulimit的open file,系统默认的ulimit对文件打开数量的限制是1024
# ulimit -HSn 102400 //这只是在当前终端有效,退出之后,open files又变为默认值。当然也可以写到/etc/profile中,因为每次登录终端时,都会自动执行/etc/profile
或
# vim /etc/security/limits.conf //加入以下配置,重启即可生效
* soft nofile 65535
* hard nofile 65535
ulimit命令
-H 使用硬资源控制
-S 使用软资源控制
-a 查看所有的当前限制
-n 能打开的最大文件描述符数
-t 限制最大的 CPU 占用时间(每秒)
-u 限制最大用户进程数
-v 限制虚拟内存大小(kB)
ulimit -HSn 65536 #硬资源和软资源同时限制为最大打开文件描述符数65546
ulimit -v ulimited #将虚拟内存限制改为无限制
附录:
附录1.
为了让一个程序的open files数目扩大,可以在启动脚本前面加上ulimit -HSn 102400命令。但当程序是一个daemon时,可能这种方法无效,因为没有终端。
附录2.
如果某项服务已经启动,再动态调整ulimit是无效的,特别是涉及到线上业务就更麻烦了。
这时,可以考虑通过修改/proc/’程序pid’/limits来实现动态修改!!!
注明:
查看linux系统哪些进程打开了file:
用lsof -p [进程ID] 可以看到某ID的打开文件状况。
进程ID可能用 ps -ef|grep java列出weblogic的进程ID,然后用此ID套入lsof -p ID号,咳,一大堆的请求哟,这显然是网络请求过多造成了 Too many open files。
适当调整后便已消除这种现象。
当前默认设置的最大文件数 ulimit -n
系统打开最大文件数: cat /proc/sys/fs/file-max
统计当前某个用户打开的文件数(包含socket数和会话数) lsof -u username|wc -l
统计当前所有进程的文件打开数 lsof |egrep -v 'TCP|UDP'|awk '{print $8}' |sort |uniq |wc -l
分析当前进程打开文件数的排序并此打开文件数最多的进程打开了哪些文件。
lsof |egrep -v 'TCP|UDP'|awk '{print $2}' |sort -n |uniq -c |sort -nr |head -n1
假如结果为 125 1150,第一个数字是个数,第二个数字是pid
lsof -p 1150
查看当前的打开最大数文件数的设置参数:cat /etc/security/limits.conf
查看当前线程总数
echo "`ps -eLf |awk '{print $6}'|grep -v NLWP |xargs |sed 's/ /+/g'`" |bc
查看当前进程数: ps aux |grep -v 'USER'|wc -l
统计SOCKE联接数: netstat |awk '$1=="unix"'|wc -l
当然我们可以利用脚本动态统计某个进程的文件打开数
sh-4.1# more test.sh
#/bin/sh
while :; do
sleep 1800
lsof -p 29728 |wc -l
done
上面创建了一个test.sh脚本,每1800秒(半个钟)统计29728进程的文件打开数,while :; 的意思是死循环
然后将test.sh放到后台执行,执行的信息放在openfiles.txt这个文件中
sh-4.1# nohup ./test.sh > openfiles.txt 2>&1 &
sh-4.1# ps -ef | grep test.sh
root 15030 14812 0 11:45 pts/0 00:00:00 /bin/sh ./test.sh