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