Linux伺服器中, 經常發生"error: too many open files", 或者 "ulimit: max user processes: cannot modify limit" 類型的錯誤, 這些問題為什麼會發生? 又要如何解決? 本文記錄了我遇到問題、解決問題的過程, 最後還對u... ...
目錄
1 問題說明
Linux 系統預設的max open files = 1024
, 在大記憶體伺服器中, 如果運行負載比較大的程式, 很容易發生error: too many open files
, 特別是提供大量靜態文件訪問的Web伺服器、緩存伺服器中這種錯誤更加常見.
open files
表示系統級別的能夠打開的文件句柄的數量, 是系統級別的安全策略: 限制所有應用打開的文件數量.
發生error: too many open files
時, 如果不好定位程式問題, 可在系統的配置文件中做一定的修改.
為了讓伺服器重啟之後, 配置仍然有效, 需要用永久生效的配置方法進行修改.
2 修改max 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) 65536 # 最大打開文件數
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 65536 * hard nofile 65536
修改完成後保存, 退出當前用戶並重新登錄(不用重啟伺服器), 當前修改就會生效.
② 在
/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 伺服器所支持的最大句柄數調高數倍(與伺服器的記憶體數量相關)。
3 修改max user processes
(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很接近,
# 因為物理頁面會存儲一些關鍵數據, 所以實際的比計算出來的要小一些.
4 附錄: ulimit命令說明
(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) 65536 # 每個進程可以同時打開的最大文件數, 不能是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 兩者的極限值.
參考資料
版權聲明
作者: ma_shoufeng(馬瘦風)
出處: 博客園 馬瘦風的博客
您的支持是對博主的極大鼓勵, 感謝您的閱讀.
本文版權歸博主所有, 歡迎轉載, 但請保留此段聲明, 併在文章頁面明顯位置給出原文鏈接, 否則博主保留追究相關人員法律責任的權利.