1. 程式人生 > 其它 >Linux 系統檔案控制代碼數(nofile)、程序數(nproc) 限制 Too many open files

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一切都是檔案,而檔案控制代碼限制,就是規定的單個程序能夠開啟的最大檔案控制代碼數量(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