linux日志显示too many open files解决

某linux服务器的日志每隔几天就会报错。内容如下:

[2012-02-22 09:50:00,119] ERROR ipnet.dc.pmprobe.SnmpScalarQueryJoe.execute()(146) – Too many open files       java.net.SocketException: Too many open files
向同事咨询了一下,一般报Too many open files的错,表示文件句柄数超出最大。对linux系统来说,默认的最大值为1024,在系统并发比较大的时候,这个很容易超过该值。文件句柄数大小可以通过命令ulimit -a查看。

ulimit

用命令ulimit -a查看

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

scheduling priority             (-e) 0

file size               (blocks, -f) unlimited

pending signals                 (-i) 256751

max locked memory       (kbytes, -l) 64

max memory size         (kbytes, -m) unlimited

open files                      (-n) 1024

pipe size            (512 bytes, -p) 8

POSIX message queues     (bytes, -q) 819200

real-time priority              (-r) 0

stack size              (kbytes, -s) 10240

cpu time               (seconds, -t) unlimited

max user processes              (-u) 256751

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited

为避免因程序任务过多导致文件句柄数不够的问题,在linux系统下部署程序的时候可以调大用户文件句柄数。用root用户修改/etc/security/limits.conf 配置,在文件末尾添加如下内容:
user           soft    nofile  2048
user           hard    nofile  65536
其中user为报错程序部署目录的用户名,根据部署环境配置。注意”nofile”项有两个可能的限制措施。就是<type>项下的hard和soft。硬限制表明soft限制中所能设定的最大值。soft限制指的是当前系统生效的设置值。hard限制值可以被普通用户降低。但是不能增加。soft限制不能设置的比hard限制更高。只有root用户才能够增加hard限制值。

修改完成后切换到user用户下再执行ulimit -a查看文件句柄数是否修改成功。

改完后,验证,发现用户的文件句柄数已变成2048.应该可以应对大并发数啦。

这里只是修改最大句柄数,另外一个问题,如何知道当前进程打开了多少个文件句柄呢?可以通过下面一段小脚本可以帮你查看:

[root@VM192168200201 etc]# lsof -n|awk '{print $2}'|sort|uniq -c |sort -nr|more
738 26249
164 16540
154 16538
150 16581
135 16640
135 16638
134 16990
131 16615
121 16095
119 16617
118 16510
116 16600
115 16548
110 16636
104 16545
94 3684
90 20160

lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。

通过这个命令可以按照从大到小的顺序查看各进程共打开了多少文件句柄数。第一列为数量,第二列为进程号。然后再用pwdx 进程号   查看最大的进程路径,ps -ef|grep 进程号   查看程序名称。

Leave a Reply

Your email address will not be published. Required fields are marked *