1. 概述
1.1 問題描述
Linux 伺服器中部署帆軟應用時,出現報錯開啟的檔案過多或者too many open files,如下圖所示:
1.2 原因分析
Linux 系統對每個登入使用者開啟的最大檔案數有限制。
在一些併發或多執行緒情況下, 需要手動改掉 Linux 系統的最大開啟檔案數,以突破限制。該修改在不同情況下會涉及到 3 個關鍵值。
2. 參數說明
2.1 參數介紹
參數 | 說明 | 預設值 |
---|---|---|
nofile | 單個進程的最大開啟檔案數 | 1024 |
nr_open | 單個進程可分配的最大檔案數 | 1024*1024=1048576 |
file-max | 系統核心一共可以開啟的最大值 | 185745 |
2.2 修改策略
一般情況下,nofile 的值不允許超過 nr_open 和 file-max 的值。因此在修改 nofile 時要考慮是否超過以上兩個值的情況:
當要修改的「nofile」值未超過「nr_open」和「file-max」兩個值時,直接修改「nofile」值即可。
當要修改的「nofile」值超過「nr_open」和「file-max」兩個值時,不僅要修改「nofile」的值,還要修改「nr_open」和「file-max」的值滿足「大於nofile」值。
2.3 查看參數大小
基於修改策略,請在執行下文的修改操作前,先查看各個參數的大小。
參數 | 查詢語句 |
---|---|
nofile | ulimit -n |
nr_open | cat /proc/sys/fs/nr_open |
file-max | cat /proc/sys/fs/file-max |

3. 修改 nofile 值
當要修改的「nofile」值(最大開啟檔案數)未超過「nr_open」和「file-max」兩個值時,直接修改「nofile」值即可。
3.1 臨時生效
1)使用終端工具連結伺服器,執行命令:ulimit -n 128000
2)該修改只會影響當前shell對話。如果你開啟一個新的終端視窗,nofile 限制將恢復為系統設定值。
3.2 永久生效
參考3.1節步驟後,直接執行 reboot 重啟 Linux 伺服器,即可永久生效;
若不想重啟伺服器,可參考本節完整步驟。
1)使用vi /etc/security/limits.conf編輯 limits.conf 檔案,修改 nofile 值(其中 128000 即為修改的 nofile 值),如下所示:
注:有的系統需把「*」更換為具體帳號才生效,例如 root soft nofile 128000
2)編輯/etc/pam.d/login檔案,確定有下面內容,並儲存。如下圖所示:
3)使用exit語句跳出終端重新登入即可。如下圖所示:
4. nr_open 和 file-max 值
4.1 臨時生效
4.2 永久生效:需重啟伺服器
當要修改的最大開啟檔案數超過 nr_open 和 file-max 時,就需要改動該值,將該值提高。其修改方式如下:
在檔案/proc/sys/fs/nr_open
中加入如下程式碼:(1200000 為修改的參數值)
在檔案 /proc/sys/fs/file-max 中插入如下程式碼:
儲存並執行 reboot 重啟伺服器。
注:Linux的核心參數 nr_open 只有在核心版本是 2.6.25 之後的版本才可設定。查看核心版本使用命令“uname -a”。
然後再修改 nofile 值 ,請參見 3.2 節。
4.3 永久生效:無需重啟伺服器
在/etc/sysctl.conf中設定fs.nr_open= 1200000 fs.file-max=200000,然後執行sysctl -p,使配置生效。如下所示:
4.4 效果查看
透過cat /proc/pid/limits查看單進程最大開啟檔案數,如下圖所示:
5. 注意事項
5.1 nofile修改不生效
問題描述
參考文檔第三章修改nofile值不生效,仍為之前的值。
原因及解決方案
檢查/etc/profile檔案中,是否存在 ulimit -n xxx相關語句,刪除即可
5.2 普通使用者修改未生效
問題描述
參考本文4.3節無需重啟伺服器的步驟後,普通使用者修改未生效,使用 ssh 連結 Linux 報錯:ulimit: open files: cannot modify limit: Operation not permitted
原因分析
該問題發生在 openssh 升級之後,且只有 ssh 登入才發生此問題,與 ssh 有關。
解決方案
1)修改sshd_config檔案,將#UseLogin no修改為UseLogin yes,如下所示:
2)使用service sshd restart重啟 ssh 服務。