linux查看文件打开数量

2018-09-26 15:26:08 u010320108 阅读数 4658
  • 红帽Linux企业内训之RHEL系统安装

    本课程基于红帽企业版Linux即RHEL(RHEL是Red Hat Enterprise Linux的缩写),在课程中讲解了RHEL的安装、基础网络命令、网卡设置、文件与目录管理、进程与线程管理、VI编辑器、用户与权限、软件包管理、如何快速地...

    2298课时 0分钟 6683人学习 杨璞
    免费试看

做高并发服务器或者像聊天这种长连接服务时,需要修改系统能够打开的文件句柄数。否则会出现 too many open files 的错误。socket句柄和文件句柄是相同的,像聊天这种长链接服务,此时too many open files 指的就是socket句柄数超出了系统的限制。

单进程文件句柄限制

句柄数限制又分为系统总限制和单进程限制。使用命令 ulimit -n 可以看到系统对于单个进程的限制,即open files。执行命令 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) 7285
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7285
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

open files 65535 表示我当前登录的用户(root),每个进程可以打开65535个句柄,当然总和不能超过 file-max 限制。file-max下面说。

修改open files的值,有两种方法,临时的和永久的

临时修改 open files

ulimit -HSn 1000 将open-files 修改为1000,退出当前shell后即失效。H和S选项表示硬限制和软限制,下面有解释,省略的话表示同时修改。(用当前shell启动的其他daemon进程是不是也跟着失效?)

永久修改 open files

若希望永久生效的话就得修改配置文件,/etc/security/limits.conf,修改后需要重启系统,该文件内容为

root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535
  1. 第一列表示对哪些用户进程进行限制,* 表示所有用户。
  2. 第二列
       soft: 表示软限制,当进程打开的句柄数超过该限制后,只是进行警告。
       hard:表示硬限制,进程最多打开这么多句柄。
  3. 第三列nofile 表示能够打开的最大文件数(其他配置值可以参考文件中的注释,与 ulimit -a 列出的值一一对应)
  4. 第四列是具体的值,这个值也是有上限的,这个上限的值设置在 /proc/sys/fs/nr_open ,默认值为 1048576,完全够用了。
    nr_open 表示一个线程最多能分配的文件句柄数
cat /proc/sys/fs/nr_open
1048576

系统总打开文件句柄限制

上面的 open files 是对单个进程的限制,属于线程级别的。系统级的限制在这个文件中 /proc/sys/fs/file-max

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

file-max指定了系统范围内所有进程可以打开的文件句柄限制。
同样,修改上面那个文件也是临时生效的,重启后会失效。如果要永久生效,则要修改这个文件, /etc/sysctl.conf

fs.file-max  = 6815744

如果没有这一项,则新加这一项就行。运行 sysctl -p 或重启后才能生效。

lsof -p 进程pid 查看单个进程打开的文件句柄
/proc/sys/fs/file-nr记录当前系统打开的句柄数

cat /proc/sys/fs/file-nr
1184	0	6815744
  1. 第一列表示已打开的句柄数
  2. 第二列表示已分配但是未使用的句柄数
  3. 第三列表示系统总的句柄数,即 file-max

总结(总结抄的别人的,后面有链接)

  1. 所有进程能够打开的文件句柄总数不能超过 file-max
  2. 单个进程打开的句柄数不能超过nofile soft limit
  3. nofile soft limit 的设置不能超过nofile hard limit
  4. nofile hard limit 的设置不能超过 no_open
  5. no_open 的设置不能超过 file-max

还有一点不明白,这个file-max和open files设置多少合适,跟系统cpu和内存以及网卡磁盘有什么关系?

参考:https://blog.csdn.net/windowschengxisheji/article/details/51027449

2019-08-08 12:35:00 b078109 阅读数 206
  • 红帽Linux企业内训之RHEL系统安装

    本课程基于红帽企业版Linux即RHEL(RHEL是Red Hat Enterprise Linux的缩写),在课程中讲解了RHEL的安装、基础网络命令、网卡设置、文件与目录管理、进程与线程管理、VI编辑器、用户与权限、软件包管理、如何快速地...

    2298课时 0分钟 6683人学习 杨璞
    免费试看

1、查看打开文件数量限制

ulimit -a
ulimit -n

2、临时修改

ulimit -n 2048

3、永久修改

vi /etc/security/limits.conf
追加
* soft nofile 65535
* hard nofile 65535

注意前面的星号(*)要保留

 

 

转载于:https://www.cnblogs.com/asker009/p/11320449.html

2015-12-18 20:21:00 weixin_33698043 阅读数 32
  • 红帽Linux企业内训之RHEL系统安装

    本课程基于红帽企业版Linux即RHEL(RHEL是Red Hat Enterprise Linux的缩写),在课程中讲解了RHEL的安装、基础网络命令、网卡设置、文件与目录管理、进程与线程管理、VI编辑器、用户与权限、软件包管理、如何快速地...

    2298课时 0分钟 6683人学习 杨璞
    免费试看

linux打开文件数量的查看方法

linux打开文件数量的查看方法在网上查到两种查看linux打开文件数量的查看方法,但结果不相同,linux查看文件打开数量是以那个文件或命令为标准呢?

搜索过关于ulimit命令的一些用法,其中有
ulimit -n 4096
也就是限制用户的最大文件打开数为4096个

在网上查了关于怎么查看文件打开数的文章大致有两种说法

/proc/sys/fs/file-nr 
该文件与 file-max 相关,它有三个值: 

已分配文件句柄的数目 
已使用文件句柄的数目 
文件句柄的最大数目 
该文件是只读的,仅用于显示信息。 

查看所有进程的文件打开数
lsof |wc -l
 
/usr/sbin/lsof -p 27419 |wc -l
 
查看某个进程打开的文件数
lsof -p pid |wc -l
2019-03-05 09:25:59 Keep_on_Growing 阅读数 4548
  • 红帽Linux企业内训之RHEL系统安装

    本课程基于红帽企业版Linux即RHEL(RHEL是Red Hat Enterprise Linux的缩写),在课程中讲解了RHEL的安装、基础网络命令、网卡设置、文件与目录管理、进程与线程管理、VI编辑器、用户与权限、软件包管理、如何快速地...

    2298课时 0分钟 6683人学习 杨璞
    免费试看

查看所有进程打开的文件数量:

lsof |wc -l

查看某个进程打开的文件数:

lsof -p pid|wc -l # pid为进程id

查看进程id:

top

 

2014-05-06 09:44:15 sd4015700 阅读数 4845
  • 红帽Linux企业内训之RHEL系统安装

    本课程基于红帽企业版Linux即RHEL(RHEL是Red Hat Enterprise Linux的缩写),在课程中讲解了RHEL的安装、基础网络命令、网卡设置、文件与目录管理、进程与线程管理、VI编辑器、用户与权限、软件包管理、如何快速地...

    2298课时 0分钟 6683人学习 杨璞
    免费试看
  ulimit -n 4096
    也就是限制用户的最大文件打开数为4096个
    在网上查了关于怎么查看文件打开数的文章大致有两种说法
    /proc/sys/fs/file-nr
    该文件与 file-max 相关,它有三个值:
    已分配文件句柄的数目
    已使用文件句柄的数目
    文件句柄的最大数目
    该文件是只读的,仅用于显示信息。
    查看所有进程的文件打开数
    lsof |wc -l
    查看某个进程打开的文件数
    lsof -p pid |wc -l
 
系统设置--ulimit
语  法:ulimit [-aHS] [-c <core文件上限>][-d <数据节区大小>][-f <文件大小>][-m <内存大小>][-n <文件数目>][-p <缓冲区大小>][-s <堆叠大小>][-t <CPU时间>][-u <程序数目>][-v <虚拟内存大小>]

补充说明:ulimit为shell内建指令,可用来控制shell执行程序的资源。

参  数:
  -a  显示目前资源限制的设定。 
  -c <core文件上限>  设定core文件的最大值,单位为区块。 
  -d <数据节区大小>  程序数据节区的最大值,单位为KB。 
  -f <文件大小>  shell所能建立的最大文件,单位为区块。 
  -H  设定资源的硬性限制,也就是管理员所设下的限制。 
  -m <内存大小>  指定可使用内存的上限,单位为KB。 
  -n <文件数目>  指定同一时间最多可开启的文件数。 
  -p <缓冲区大小>  指定管道缓冲区的大小,单位512字节。 
  -s <堆叠大小>  指定堆叠的上限,单位为KB。 
  -S  设定资源的弹性限制。 
  -t <CPU时间>  指定CPU使用时间的上限,单位为秒。 
  -u <程序数目>  用户最多可开启的程序数目。 
  -v <虚拟内存大小>  指定可使用的虚拟内存上限,单位为KB。
 
 
Linux系统的文件句柄数量问题
linux下面部署应用的时候,有时候会遇上socket/file: can‘t open so many files的问题,其实linux是有文件句柄限制的(就像winxp?),而且默认不是很高,一般都是1024,作为一台生产服务器,其实很容易就达到这个数量,因此我们需要把这个值改大一些。
 
  大概知道ulimit这个命令是相关的,上google搜索了一下,大多数说的很含糊,也没有统一说一下,经过两个小时看了不少文章终于弄清楚ulimit相关的一些配置问题。
 
  我们可以用ulimit -a来查看所有限制值,我只关心文件句柄数量的问题
 
  open files (-n) 1024
 
  这个就是限制数量
 
  这里,有很多ulimit的文章都说的很含糊,究竟这个1024是系统的限制,还是用户的限制呢。其实,这个是用户限制来的,完整的说法,应该是当前用户准备要运行的程序的限制。
 
  1、这个限制是针对单个程序的限制
 
  2、这个限制不会改变之前已经运行了的程序的限制
 
  3、对这个值的修改,退出了当前的shell就会消失
 
  比如说,我先运行了一个程序a,然后通过ulimit修改了限制为2048,然后运行b,然后退出了shell再登录,然后运行c.那就只有b可以打开2048个句柄。
 
  如果我们需要改变整体的限制值,或者我们运行的程序是系统启动的,应该怎么处理呢
 
  其中一个方法,是想ulimit修改命令放入/etc/profile里面,但是这个做法并不好
 
  正确的做法,应该是修改/etc/security/limits.conf
 
  里面有很详细的注释,比如
 
  * soft nofile 2048
 
  * hard nofile 32768
 
  就可以将文件句柄限制统一改成软2048,硬32768
 
  这里涉及另外一个问题,什么是软限制,什么是硬限制
 
  硬限制是实际的限制,而软限制,是warnning限制,只会做出warning
 
  其实ulimit命令本身就有分软硬设置,加-h就是硬,加-s就是软
 
  默认显示的是软限制,如果修改的时候没有加上的话,就是两个一起改
 
  配置文件最前面的一位是domain,设置为星号代表全局,另外你也可以针对不同的用户做出不同的限制
 
  修改了,重新登录用ulimit一开就立刻生效了,不过之前启动过的程序要重新启动才能使用新的值。我用的是centos,似乎有些系统需要重启才能生效。
 
  ulimit其实就是对单一程序的限制
 
  那系统总限制呢
 
  其实是在这里,/proc/sys/fs/file-max
 
  可以通过cat查看目前的值,echo来立刻修改
 
  另外还有一个,/proc/sys/fs/file-nr
 
  只读,可以看到整个系统目前使用的文件句柄数量
 
  查找文件句柄问题的时候,还有一个很实用的程序lsof 
  可以很方便看到某个进程开了那些句柄
 
  也可以看到某个文件/目录被什么进程占用了。


 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Linux 最大文件数(转)

1、修改用户进程可打开文件数限制

Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄)。可使用ulimit命令查看系统允许当前用户进程打开的文件数限制:
[speng@as4 ~]$ ulimit -n
1024
这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中还得除去每个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,进程间通讯的unixsocket等文件,那么剩下的可用于客户端socket连接的文件数就只有大概1024-10=1014个左右。也就是说缺省情况下,基于Linux的通讯程序最多允许同时1014TCP并发连接。

对于想支持更高数量的TCP并发连接的通讯处理程序,就必须修改Linux对当前用户的进程同时打开的文件数量的软限制(soft limit)和硬限制(hardlimit)。其中软限制是指Linux在当前系统能够承受的范围内进一步限制用户同时打开的文件数;硬限制则是根据系统硬件资源状况(主要是系统内存)计算出来的系统最多可同时打开的文件数量。通常软限制小于或等于硬限制。

修改上述限制的最简单的办法就是使用ulimit命令:
[speng@as4 ~]$ ulimit -n <file_num>
上述命令中,在<file_num>中指定要设置的单一进程允许打开的最大文件数。如果系统回显类似于“Operation notpermitted”之类的话,说明上述限制修改失败,实际上是因为在<file_num>中指定的数值超过了Linux系统对该用户打开文件数的软限制或硬限制。因此,就需要修改Linux系统对用户的关于打开文件数的软限制和硬限制。

第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:
speng soft nofile 10240
speng hard nofile 10240

其中speng指定了要修改哪个用户的打开文件数限制,可用'*'号表示修改所有用户的限制;softhard指定要修改软限制还是硬限制;10240则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于或等于硬限制)。修改完后保存文件。

第二步,修改/etc/pam.d/login文件,在文件中添加如下行:
session required /lib/security/pam_limits.so
这是告诉Linux在用户完成系统登录后,应该调用pam_limits.so模块来设置系统对该用户可使用的各种资源数量的最大限制(包括用户可打开的最大文件数限制),而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值。修改完后保存此文件。

第三步,查看Linux系统级的最大打开文件数限制,使用如下命令:
[speng@as4 ~]$ cat /proc/sys/fs/file-max
12158
这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)12158个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不应超过这个数值。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不应该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值。修改此硬限制的方法是修改/etc/rc.local脚本,在脚本中添加如下行:
echo 22158 > /proc/sys/fs/file-max
这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为22158。修改完后保存此文件。

完成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时打开的最大文件数限制设为指定的数值。如果重启后用 ulimit-n命令查看用户可打开文件数限制仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用 ulimit-n命令已经将用户可同时打开的文件数做了限制。由于通过ulimit-n修改系统对用户可同时打开文件的最大数限制时,新修改的值只能小于或等于上次ulimit-n设置的值,因此想用此命令增大这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本文件,在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数量,如果找到,则删除这行命令,或者将其设置的值改为合适的值,然后保存文件,用户退出并重新登录系统即可。
通过上述步骤,就为支持高并发TCP连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。

2、修改网络内核对TCP连接的有关限制

Linux上编写支持高并发TCP连接的客户端通讯处理程序时,有时会发现尽管已经解除了系统对用户同时打开文件数的限制,但仍会出现并发TCP连接数增加到一定数量时,再也无法成功建立新的TCP连接的现象。出现这种现在的原因有多种。

第一种原因可能是因为Linux网络内核对本地端口号范围有限制。此时,进一步分析为什么无法建立TCP连接,会发现问题出在connect()调用返回失败,查看系统错误提示消息是“Can't assign requestedaddress”。同时,如果在此时用tcpdump工具监视网络,会发现根本没有TCP连接时客户端发SYN包的网络流量。这些情况说明问题在于本地Linux系统内核中有限制。其实,问题的根本原因在于Linux内核的TCP/IP协议实现模块对系统中所有的客户端TCP连接对应的本地端口号的范围进行了限制(例如,内核限制本地端口号的范围为1024~32768之间)。当系统中某一时刻同时存在太多的TCP客户端连接时,由于每TCP客户端连接都要占用一个唯一的本地端口号(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满,则此时就无法为新的TCP客户端连接分配一个本地端口号了,因此系统会在这种情况下在connect()调用中返回失败,并将错误提示消息设为“Can't assignrequested address”。有关这些控制逻辑可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c文件中如下函数:
static int tcp_v4_hash_connect(struct sock *sk)
请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range的初始化则是在tcp.c文件中的如下函数中设置:
void __init tcp_init(void)
内核编译时默认设置的本地端口号范围可能太小,因此需要修改此本地端口范围限制。
第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_local_port_range = 1024 65000
这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须大于或等于1024;而端口范围的最大值则应小于或等于65535。修改完后保存此文件。
第二步,执行sysctl命令:
[speng@as4 ~]$ sysctl -p
如果系统没有错误提示,就表明新的本地端口范围设置成功。如果按上述端口范围进行设置,则理论上单独一个进程最多可以同时建立60000多个TCP客户端连接。

第二种无法建立TCP连接的原因可能是因为Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数有限制。此时程序会表现为在 connect()调用中阻塞,如同死机,如果用tcpdump工具监视网络,也会发现根本没有TCP连接时客户端发SYN包的网络流量。由于 IP_TABLE防火墙在内核中会对每个TCP连接的状态进行跟踪,跟踪信息将会放在位于内核内存中的conntrackdatabase中,这个数据库的大小有限,当系统中存在过多的TCP连接时,数据库容量不足,IP_TABLE无法为新的TCP连接建立跟踪信息,于是表现为在connect()调用中阻塞。此时就必须修改内核对最大跟踪的TCP连接数的限制,方法同修改内核对本地端口号范围的限制是类似的:
第一步,修改/etc/sysctl.conf文件,在文件中添加如下行
net.ipv4.ip_conntrack_max = 10240
这表明将系统对最大跟踪的TCP连接数限制设置为10240。请注意,此限制值要尽量小,以节省对内核内存的占用。
第二步,执行sysctl命令
[speng@as4 ~]$ sysctl -p
如果系统没有错误提示,就表明系统对新的最大跟踪的TCP连接数限制修改成功。如果按上述参数进行设置,则理论上单独一个进程最多可以同时建立10000多个TCP客户端连接。

3、使用支持高并发网络I/O的编程技术

Linux上编写高并发TCP连接应用程序时,必须使用合适的网络I/O技术和I/O事件分派机制。

可用的I/O技术有同步I/O,非阻塞式同步I/O(也称反应式I/O),以及异步I/O。在高TCP并发的情形下,如果使用同步I/O,这会严重阻塞程序的运转,除非为每个TCP连接的I/O创建一个线程。但是,过多的线程又会因系统对线程的调度造成巨大开销。因此,在高TCP并发的情形下使用同步I /O是不可取的,这时可以考虑使用非阻塞式同步I/O或异步I/O。非阻塞式同步I/O的技术包括使用select()poll()epoll等机制。异步I/O的技术就是使用AIO

I/O事件分派机制来看,使用select()是不合适的,因为它所支持的并发连接数有限(通常在1024个以内)。如果考虑性能,poll()也是不合适的,尽管它可以支持的较高的TCP并发数,但是由于其采用轮询机制,当并发数较高时,其运行效率相当低,并可能存在I/O事件分派不均,导致部TCP连接上的I/O出现饥饿现象。而如果使用epollAIO,则没有上述问题(早期Linux内核的AIO技术实现是通过在内核中为每个I /O请求创建一个线程来实现的,这种实现机制在高并发TCP连接的情形下使用其实也有严重的性能问题。但在最新的Linux内核中,AIO的实现已经得到改进)

综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epollAIO技术来实现并发的TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。