Linux 系统文件句柄数(nofile)、进程数(nproc) 限制 Too many open files

  关于文件句柄数和线程数,这两篇文章讲的不错:

       https://www.cnblogs.com/sxdcgaq8080/p/11136887.html

       https://www.cnblogs.com/sxdcgaq8080/p/11136952.html

 

  最近测试同事在做压力测试的时候,Linux上的Java程序报异常:Too many open files

Linux 系统文件句柄数(nofile)、进程数(nproc) 限制 Too many open files

   Linux一切都是文件,而文件句柄限制,就是规定的单个进程能够打开的最大文件句柄数量(Socket连接也算在里面)

  Linux的 limit 限制分为2个策略:软限制和硬限制,硬限制就是实际的限制,而软限制是警告限制,它只会给出警告。

  通过ulimit -a 可以查看当前所有的limit信息,-S 是软限制,-H是硬限制,默认是软限制:

  查看 limit 软限制(等同于 ulimit -Sa):

[root@ylserver106860142 ~]# 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) 79571
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) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 79571
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

  查看 limit 硬限制:

[root@ylserver106860142 ~]# ulimit -Ha
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 79571
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 4096
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) unlimited
cpu time               (seconds, -t) unlimited
max user processes              (-u) 79571
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

 

  文件句柄

  通过 ulimit -Hn 命令可以看到默认每个进程的文件句柄硬限制为4096,其实通过 /proc/PID 目录也可以查到到进程相关信息

  先查看进程的PID号:

[root@ylserver106860142 ~]# ps aux|grep -v grep |grep demo.jar
root     20506 16.6 10.1 11322224 2059868 pts/1 Sl  14:03  49:00 /usr/local/java/jdk1.8.0_111/jre/bin/java -jar demo.jar
[root@ylserver106860142 ~]# 

  通过PID号查看进程的 limit 信息,默认文件句柄硬限制为4096:

[root@ylserver106860142 ~]# cat /proc/20506/limits 
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            8388608              unlimited            bytes     
Max core file size        0                    unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             79571                79571                processes 
Max open files            4096                 4096                 files     
Max locked memory         65536                65536                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       79571                79571                signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us        

  查看进程持有的句柄数,上面的 Too many open files 原因也就是由此而来:

[root@ylserver106860142 ~]# ls  /proc/20506/fd/|wc -l
4096
[root@ylserver106860142 ~]# 

  永久修改文件句柄限制:

[root@ylserver106860142 ~]# cat  /etc/security/limits.conf |egrep -v "#|^$"
* soft nofile 655350
* hard nofile 655350
[root@ylserver106860142 ~]# 

  重开一个终端,查看是否生效:

[root@ylserver106860142 ~]# ulimit  -Hn
655350
[root@ylserver106860142 ~]# 

  将程序重启后,查看进程 文件句柄限制信息:

[root@ylserver106860142 ~]# cat   /proc/19091/limits |grep "open"
Max open files            655350               655350               files     
[root@ylserver106860142 ~]# 

  查看进程持有的文件句柄数,可以看到已经超过4096:

[root@ylserver106860142 ~]# ls /proc/19091/fd/|wc -l
4493
[root@ylserver106860142 ~]# 

  如果是systemd service服务,则需要在对应的service文件添加 LimitNOFILE=655350 

  

  系统级文件限制

  上面讲的都是基于单个进程的文件句柄限制,查看Linux系统最大的文件句柄限制:

[root@ylserver106860142 ~]# cat /proc/sys/fs/file-max
2016339
[root@ylserver106860142 ~]# 

  修改最大文件句柄限制:

[root@ylserver106860142 ~]# echo   "fs.file-max = 6553560"  >> /etc/sysctl.conf
[root@ylserver106860142 ~]# sysctl -p
fs.file-max = 6553560
[root@ylserver106860142 ~]# 

  验证一下:

[root@ylserver106860142 ~]# cat /proc/sys/fs/file-max
6553560
[root@ylserver106860142 ~]# 

  

  进程数限制

  跟文件句柄一样,每个用户都有进程数限制,在Linux下运行多线程时,每个线程的实现其实是一个轻量级的进程,对应的术语是: light weight process(LWP)

  配置每个用户进程数上限(nproc):

[root@ylserver106860142 ~]# cat  /etc/security/limits.d/20-nproc.conf |grep -v "#"
* soft nproc 204800
* hard nproc 204800

  重新开一个终端,验证一下:

[root@ylserver106860142 ~]# ulimit  -u
204800

  如果是systemd service服务,则需要在对应的service文件添加 LimitNPROC=204800

  

    线程数

  使用ps 命令是加上 -L 参数可以查看线程数,在 进程的 /proc/PID/task/ 目录下也可以查看线程数

  查看 PID 为 6250 的线程数:

[root@ylserver106860142 ~]# ps -eLf|grep 6250|grep -v grep |wc -l
105
[root@ylserver106860142 ~]# ls  /proc/6250/task/|wc -l
105

  查看 root 用户的 线程总数(effective user):

[root@ylserver106860142 ~]# ps -u root  -Lf|wc -l
1927

  查看 root 用户的 线程总数(real user):

[root@ylserver106860142 ~]# ps -U root  -Lf|wc -l
1928

  这里要注意一下,进程创建的时候存在real user和effective user两个属性,ps命令统计的时候默认显示的是effective user的进程数,nproc限制值是限制的real user创建的进程线程数

       -u 参数查看的是 effective user, 使用 -U 参数查看的是 real user

 

上一篇:Linux ulimit命令


下一篇:gdb coredump怎么用