linux文件描述符

所有执行I/O操作的系统调用都以文件描述符,即一个非负整数来指代所打开的文件。文件描述符可以用来表示所有类型的已打开文件。同时,多个文件描述符可以指向同一个打开文件,因为有在不同进程中打开同一个文件的需求。

一、最大文件描述符的查看方法

1、查看系统级别最大文件描述符

[root@localhost ~]# sysctl -a | grep -i file-max --color
fs.file-max = 181927
或者
[root@localhost ~]# cat /proc/sys/fs/file-max
181927

2、查看用户级别最大文件描述符

[dev@localhost ~]$ ulimit -n
1024

二、最大文件描述符的限制

1、系统级别的限制

它是限制所有用户打开文件描述符的总和。一般是系统内存的10%(以KB来计算)左右。

例如我的系统:在没手动调整系统级别最大文件打开数的情况下,内存为1867048KB,系统级别的最大文件打开数为181927,正好为1/10左右。

2、用户级别的限制

ulimit可以查到用户级别的最大文件描述符限制。也就是说每一个用户登录后执行的单个进程占用文件描述符的数量不能超过这个限制。

例如:用develop用户登录之后,启动了一个tomcat进程和一个redis进程,那么tomcat这个进程占用的文件描述符不能超过ulimit的限制,redis这个进程占用的文件描述符也不能超过ulimit的限制。

三、修改最大文件描述符

1、修改系统级别的最大文件描述符

1)临时修改(重启服务器之后失效)
[root@localhost ~]# sysctl -w fs.file-max=6553500
fs.file-max = 6553500
[root@localhost ~]# cat /proc/sys/fs/file-max
6553500

或者

[root@localhost ~]# echo 6553500 > /proc/sys/fs/file-max
[root@localhost ~]# cat /proc/sys/fs/file-max
6553500
2)永久修改

fs.file-max=6553500添加到/etc/sysctl.conf中,用sysctl -p即可。

2、修改用户级别的最大文件描述符

1)临时修改(只对当前会话起作用)
[root@localhost ~]# ulimit -SHn 65535
[root@localhost ~]# ulimit -n
65535
2)永久修改

修改**/etc/security/limits.conf**

*  hard  nofile  65535
*  soft  nofile  65535

soft 指的是当前系统生效的设置值,hard 表明系统中所能设定的最大值,所以soft<=hard,soft的限制不能比hard限制高。

四、查看目前使用的文件描述符

我的系统是CentOS7.3,lsof的版本是4.87。

1、网上的大部分说法

在网上浏览了一圈,一般都是使用lsof这个命令进行查看的,例如:

lsof | awk '{print $2}' | uniq -c | sort -rnk1 | head

首先我们试一下这个命令

[dev@localhost ~]$ lsof | awk '{print $2}' | uniq -c | sort -rnk1 | head
  23115 28398
  20043 27273
  17100 28184
  16497 27940
  16192 27341
  15481 28007
  15210 28079
  13172 24416
  12079 15437
  10788 27874

得到的结果的二列是进程的pid,第一列是这个进程占用的文件描述符。

发现这些进程占用的文件描述符是1万多甚至2万多。

得到的结论是使用lsof查看进程占用的文件描述符是不正确的,具体原因如下:

1)
lsof的结果包含了并非以fd形式打开的文件,比如用mmap方式访问文件(FD一栏显示为mem),实际并不占用fd。
其中包括了像.so这样的文件。从结果看.jar文件也是以FD为mem和具体fd编号分别打开了一次。

2)
不同版本的lsof输出结果不同。CentOS 6.6中的lsof(4.82版本)是按PID/file显示的结果。而CentOS7中的lsof(4.87版本)是按PID/TID/file的组合显示的结果,上面的lsof命令显示"打开"了很多文件的进程,只是因为这些进程运行了N个线程,而每个线程都"用到"了M个jar包,并且FD一栏分别为mem和具体fd号都分别显示了一次,就出现了2*N*M(上万条)的文件描述符的结果。

3)
如果用lsof -p ,则不按TID显示,结果数少很多。但仍包含了没有使用fd的文件。

2、正确的查看文件描述符的方法

1)查看整个系统的fd数量
sudo find /proc -print | grep -P '/proc/\d+/fd/'| wc -l

-P是可以让grep使用perl的正则表达式语法。

注意如果使用sudo ls -l /proc/*/fd/* | wc -l,结果是不对的,比上面的命令返回结果少很多。原因是实际执行是会把*扩充成具体的目录作为参数,而这个参数长度有限制。

2)查看某一个进程的fd数量
ls -l /proc/<pid>/fd | wc -l

我在服务器上查看一下pid为15437的进程

[dev@microservice001 ~]$ ls -l /proc/15437/fd | wc -l   
80

然后看一下阿里云的进程监控

在这里插入图片描述

两个值是完全一样的,证明方法是正确的。

3)查看哪个进程使用的fd最多
sudo find /proc -print | grep -P '/proc/\d+/fd/'| awk -F '/' '{print $3}' | uniq -c | sort -rn | head

参考文章:
https://www.jianshu.com/p/407c2baef92e
https://blog.csdn.net/kumu_linux/article/details/7877770

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值