红联Linux门户
Linux帮助

Linux的文件描述符个数限制导致创建文件(或socket)失败的问题

发布时间:2015-09-28 09:37:32来源:linux网站作者:chinaclock

碰到一个文件fd数量不足,导致socket创建失败的问题。

而文件描述符即fd个数其实分为两种,一种是系统本身的总的限制个数,另一种是进程能够打开的具体的限制的个数。

系统最大打开文件描述符数:/proc/sys/fs/file-max

a.查看

$ cat /proc/sys/fs/file-max

1.设置

a.临时性

# echo 1000000 > /proc/sys/fs/file-max

2.永久性:在/etc/sysctl.conf中设置

fs.file-max = 1000000


2.进程最大打开文件描述符数:user limit中nofile的soft limit

a.查看

$ ulimit -n

1800000

2.设置

a.临时性:通过ulimit -Sn设置最大打开文件描述符数的soft limit,注意soft limit不能大于hard limit(ulimit -Hn可查看hard limit),另外ulimit -n默认查看的是soft limit,但是ulimit -n 1800000则是同时设置soft limit和hard limit。对于非root用户只能设置比原来小的hard limit。

查看hard limit:

$ ulimit -Hn

1700000

设置soft limit,必须小于hard limit:

$ ulimit -Sn 1600000

2.永久性:上面的方法只是临时性的,注销重新登录就失效了,而且不能增大hard limit,只能在hard limit范围内修改soft limit。若要使修改永久有效,则需要在/etc/security/limits.conf中进行设置(需要root权限),可添加如下两行,表示用户chanon最大打开文件描述符数的soft limit为1800000,hard limit为2000000。以下设置需要注销之后重新登录才能生效:

chanon           soft    nofile          1800000

chanon           hard   nofile          2000000

设置nofile的hard limit还有一点要注意的就是hard limit不能大于/proc/sys/fs/nr_open,假如hard limit大于nr_open,注销后无法正常登录。可以修改nr_open的值:

# echo 2000000 > /proc/sys/fs/nr_open


3.查看当前系统使用的打开文件描述符数

[root@localhost bin]# cat /proc/sys/fs/file-nr

5664        0        186405

其中第一个数表示当前系统已分配使用的打开文件描述符数,第二个数为分配后已释放的(目前已不再使用),第三个数等于file-max。


4.总结:

a.所有进程打开的文件描述符数不能超过/proc/sys/fs/file-max

b.单个进程打开的文件描述符数不能超过user limit中nofile的soft limit

c.nofile的soft limit不能超过其hard limit

d.nofile的hard limit不能超过/proc/sys/fs/nr_open


但是这只是查看限制个数。

实际在查看是否是fd打开数量太多导致失败,还需要从进程中去查看,其方法:

1.当前进程分配过的文件描述符的近似的最高值

cat  /proc/进程号/status

在这个文件中会有一个FDSize字段,该字段是表示当前进程分配过的文件描述符的近似的最高值。为什么是近似,因为这里FDSize本身是不会减少的,如果刚开始打开了18个文件,则这里的FDSize等于32,若大于32,则以32为单位递增,例如33则是64;这个32的单位是依赖于系统位数的,如果是32位则是32,若是64位系统则是以64倍增。

2.实际的已经打开的fd

ls -l  /proc/进程号/fd | wc

可以统计实际打开的fd个数

在碰到的这个实际问题中,相关进程的FDSize一起来就已经到了1024,而用ulimit -n查看进程打开的fd限制刚好是1024,再用/proc/进程号/fd中去查看个数是五百多个,这时还是未真正出错的时候。但是相对来讲未起业务就已经开了很多fd了,正常运行业务需要大量socket进行传输,自然就出现了fd不够的情况。


Linux下数据传输(Socket)服务的测试工具及技巧:http://www.linuxdiyf.com/linux/4202.html

Linux系统文件描述符理解:http://www.linuxdiyf.com/linux/13896.html

Linux下如何修改文件描述符的大小:http://www.linuxdiyf.com/linux/9893.html

Linux下文件描述符:http://www.linuxdiyf.com/linux/2286.html

Linux下增大可打开文件描述符的最大数:http://www.linuxdiyf.com/linux/4535.html