在 Linux 中,程序的 Max open files(最大打開文件數,即 ulimit -n
)由多個層級的參數共同控制,具體如下:
1. 內核級全局限制(系統默認上限)
由 /proc/sys/fs/file-max
控制,該值表示整個系統允許打開的最大文件數。
查看方法:
cat /proc/sys/fs/file-max
# 輸出示例:1234567
臨時修改(重啟后失效):
sysctl -w fs.file-max=2000000
永久修改(推薦):
在 /etc/sysctl.conf
中添加或修改:
fs.file-max = 2000000
然后執行:
sysctl -p
2. 用戶級限制(PAM 模塊)
通過 /etc/security/limits.conf
或 /etc/security/limits.d/
目錄下的配置文件設置。
配置格式:
<domain> <type> <item> <value>
- domain:用戶名、組名(
@groupname
)或*
(所有用戶)。 - type:
soft
(當前會話限制)或hard
(硬限制,不可超過)。 - item:
nofile
(文件描述符限制)。 - value:具體數值。
示例(對所有用戶生效):
* soft nofile 65536
* hard nofile 131072
生效條件:
需確保 PAM 模塊加載(檢查 /etc/pam.d/common-session
):
session required pam_limits.so
3. 服務特定限制(systemd 服務)
對于通過 systemd 管理的服務(如 Kafka、Nginx),需在服務配置文件中設置。
修改方法:
- 編輯服務文件(以 Kafka 為例):
systemctl edit kafka.service
- 添加或修改以下內容:
[Service] LimitNOFILE=100000
- 重啟服務:
systemctl daemon-reload systemctl restart kafka
4. 會話級臨時限制(shell 會話)
在當前 shell 中臨時修改(僅對當前會話有效):
ulimit -n 65536 # 設置 soft 限制
ulimit -Hn 131072 # 設置 hard 限制
5. 程序內部限制
某些程序會在代碼中硬編碼最大文件數限制,需修改程序配置:
- Java 程序:通過
ulimit
或systemd
配置。 - Nginx:在
nginx.conf
中添加:worker_rlimit_nofile 65536;
6. 查看實際生效值
-
查看當前 shell 限制:
ulimit -n # soft 限制 ulimit -Hn # hard 限制
-
查看進程限制:
cat /proc/<PID>/limits | grep "Max open files" # 示例: # Max open files 65536 131072 files
配置優先級(從低到高)
- 內核默認值(
/proc/sys/fs/file-max
) - 用戶全局限制(
/etc/security/limits.conf
) - systemd 服務限制(
service.conf
) - 會話臨時限制(
ulimit
命令) - 程序內部硬編碼限制
最佳實踐
- 調整順序:先改系統全局(
file-max
),再改用戶限制,最后針對特定服務配置。 - 監控工具:使用
lsof
或ss
監控系統打開文件數:lsof | wc -l # 查看系統當前打開的文件總數
- 生產環境建議:
- 對于高并發服務(如 Kafka、Elasticsearch),設置
nofile
為 100000+。 - 確保
fs.file-max
大于所有服務nofile
的總和。
- 對于高并發服務(如 Kafka、Elasticsearch),設置
通過以上配置,可有效提升系統允許的最大文件打開數,避免 “Too many open files” 錯誤。