Linux伺服器中, 經常發生"error: too many open files", 或者 "ulimit: max user processes: cannot modify limit" 類型的錯誤, 這些問題為什麼會發生? 又要如何解決? 本文記錄了我遇到問題、解決問題的過程, 最後還對ulimit指令的使用作了簡單的說明.
目錄
- 1 問題說明
- 2 修改max open files
- 3 修改max user processes
- 4 附錄: ulimit指令說明
- 參考資料
- 版權聲明
Linux 系統預設的
max open files = 1024
, 在大記憶體伺服器中, 如果運作負載比較大的程式, 很容易發生
error: too many open files
, 特别是提供大量靜态檔案通路的Web伺服器、緩存伺服器中這種錯誤更加常見.
open files
表示系統級别的能夠打開的檔案句柄的數量, 是系統級别的安全政策: 限制所有應用打開的檔案數量.
發生
error: too many open files
時, 如果不好定位程式問題, 可在系統的配置檔案中做一定的修改.
為了讓伺服器重新開機之後, 配置仍然有效, 需要用永久生效的配置方法進行修改.
說明: 這裡以Cent OS 6.5為例.
使用
ulimit -a
指令可以檢視目前系統的所有限制值, 括号中的指令是檢視單項限制值的方式, 比如要檢視系統可打開的最大檔案數量(open files), 就可以用
ulimit -n
指令: (具體指令說明請參考末尾部分的附錄)
[root@localhost ~]# 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) 1031426
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) 10240 # 棧大小
cpu time (seconds, -t) unlimited # CPU時間
max user processes (-u) 131072
virtual memory (kbytes, -v) unlimited # 虛拟記憶體大小
file locks (-x) unlimited
(1) 短期修改, 重新開機伺服器後即失效:
# 把檔案句柄數改為65535
ulimit -n 65535
# 也可用下屬方式修改:
ulimit -SHn 65535
# 其中-S是soft軟限制模式, -H指hard硬限制模式;
# 預設是軟限制, 如果隻指定-n, 那就會同時配置-SH.
(2) 永久修改, 重新開機伺服器也不變:
網絡上常見的方式有如下三種:
① 在最後增加如下兩行記錄:
/etc/security/limits.conf
# nofile - 可以打開的最大檔案數, *通配符表示對所有使用者有效 * soft nofile 65535 * hard nofile 65535
修改完成後儲存, 退出目前使用者并重新登入(不用重新開機伺服器), 目前修改就會生效.
② 在
中增加一行
/etc/profile
, 然後運作
ulimit -SHn 65535
source /etc/profile
指令讓修改立即生效.
——
/etc/profile
檔案是所有系統使用者的配置檔案, 修改後會影響目前系統的所有注冊使用者.
③ 在
檔案中增加一行
/etc/rc.local
, 修改完後, 重新開機伺服器就可生效.
ulimit -SHn 65535
值得注意的是, 部落客在CentOS 6.5系統中測試, 發現隻有第 ① 和第 ② 種方式才有效.
另外, 在《阿裡巴巴Java開發手冊》中, 關于最大檔案句柄數有這樣的描述:
【推薦】調大伺服器所支援的最大檔案句柄數(File Descriptor,簡寫為fd)。
說明:主流作業系統的設計是将 TCP/UDP 連接配接采用與檔案一樣的方式去管理,即一個連接配接對應于一個 fd。主流的 Linux 伺服器預設所支援最大 fd 數量為 1024,當并發連接配接數很大時很容易因為 fd 不足而出現“open too many files”錯誤,導緻新的連接配接無法建立。 建議将 Linux 伺服器所支援的最大句柄數調高數倍(與伺服器的記憶體數量相關)。
(1) 問題描述: 在使用Java程式多線程大批量生成模拟資料時, Cent OS報出如下錯誤:
ulimit: max user processes: cannot modify limit
錯誤說明: Linux系統為每個使用者都設定了一個最大程序數, 這個特性可以讓我們控制伺服器上現有使用者可以建立的程序數量.
(2) 檢視
max user processes
:
# 與檢視max open files類似, 可使用 ulimit -u檢視max user processes:
ulimit -u
(3) 修改
max user processes
① 方案一: 修改
/etc/security/limits.conf
檔案, 在檔案最後添加下述内容:
* soft nproc 131072
* hard nproc 131072
② 方案二: 修改
/etc/security/limits.d/90-nproc.conf
# 使用者程序數的預設限制, 下面這個是對root外的其他使用者限制max user processes, 要注釋掉:
# * soft nproc 1024
root soft nproc 131072
(4) 關于nproc配置資訊的擴充說明:
對
max user processes
的配置, Linux系統預設先讀取
/etc/security/limits.conf
中的資訊, 如果
/etc/security/limits.d/
目錄下還有配置檔案的話, 也會依次周遊讀取, 最終,
/etc/security/limits.d/
中的配置會覆寫
/etc/security/limits.conf
中的配置.
另外,
max open files
和
max user processes
是不能配置
unlimited
的 —— 極不安全的設定, 此時系統會使用預設的配置值. 對
nproc
而言, 預設值的計算方法為:
# 計算公式為:
default_nproc = max_threads / 2;
# 其中, max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
# mempages是機器的實體頁面個數, THREAD_SIZE=8K, 是以, 計算公式為:
default_nproc = max_threads / 2
= (mempages * PAGE_SIZE) / ( 2 * 8 *THREAD_SIZE )
= total_memory / 128K;
# 計算本機預設nproc配置:
cat /proc/meminfo | grep MemTotal
MemTotal: 115571480 kB
echo "115571480 / 128" | bc
902902
ulimit -u
902682
# 算出來default_nproc = 902902, 和實際的902682很接近,
# 因為實體頁面會存儲一些關鍵資料, 是以實際的比計算出來的要小一些.
(1) 列出所有目前資源極限, 指令為:
ulimit -a
, 其他指令可參考輸出資訊中括号内的提示:
# ulimit -a 指令的輸出資訊:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited # 一個程序的資料段的最大值
scheduling priority (-e) 0
file size (blocks, -f) unlimited # Shell建立檔案的最大體積, 1block = 512bytes
pending signals (-i) 1031426 # 最多允許多少個待處理的信号
max locked memory (kbytes, -l) 64 # 每個程序可以鎖住的實體記憶體的最大值
max memory size (kbytes, -m) unlimited # 每個程序可以使用的常駐記憶體的最大值
open files (-n) 65535 # 每個程序可以同時打開的最大檔案數, 不能是unlimited
pipe size (512 bytes, -p) 8 # 管道的最大值, 1block = 512bytes
POSIX message queues (bytes, -q) 819200 # POSIX的消息隊列的最大值
real-time priority (-r) 0
stack size (kbytes, -s) 10240 # 單個程序能夠使用的最大棧大小
cpu time (seconds, -t) unlimited # 單個程序的最大CPU時間, 也就是可使用CPU的秒數, 到硬極限時, 這個程序就會立即自殺; 到軟極限時, 每秒發送一次限制逾時信号SIGXCPU
max user processes (-u) 131072 # 單個使用者可同時運作的最大程序數, 不能是unlimited
virtual memory (kbytes, -v) unlimited # 每個程序可使用的最大虛拟記憶體
file locks (-x) unlimited # 每個程序能鎖住的最大檔案個數
(2) ulimit的其他指令:
-H 設定某個給定資源的硬極限. 如果使用者擁有root權限, 可以增大硬極限. 任何使用者均可減少硬極限
-S 設定某個給定資源的軟極限, 軟極限可增大到硬極限的值
(3) 注意事項:
① 其中,
unlimited
是指不限制使用者可以使用的資源, 但這個設定對系統可打開的最大檔案數(max open files)和各個使用者可同時運作的最大程序數(max user processes)無效.
② 如果某個名額沒有明确指定-H和-S限制, 那麼目前的極限值就是 -H 和 -S 兩者的極限值.
ulimit限制之nproc問題
linux修改max user processes limits
作者: 馬瘦風(https://healchow.com)
出處: 部落格園 馬瘦風的部落格(https://www.cnblogs.com/shoufeng)
感謝閱讀, 如果文章有幫助或啟發到你, 點個[好文要頂👆] 或 [推薦👍] 吧😜
本文版權歸部落客所有, 歡迎轉載, 但 [必須在文章頁面明顯位置标明原文連結], 否則部落客保留追究相關人員法律責任的權利.