當程式 (如 Java、Nginx、MySQL) 同時開啟大量檔案描述符超過系統預設上限 (通常 1024),即會拋出「Too many open files」。本文從臨時調整、永久生效、核心參數、使用者層級限制四個層面,提供完整解決方案與驗證方法。
# 查看核心級最大檔案數
cat /proc/sys/fs/file-max
# 查看當前 Shell 進程軟限制
ulimit -n
# 查看特定進程已開啟檔案數
lsof -p | wc -l
ulimit -n 65535 # 立即生效,僅限當前 Shell 及其後啟動的進程
/etc/security/limits.conf)編輯 /etc/security/limits.conf,新增:
* soft nofile 65535
* hard nofile 65535
root soft nofile 65535
root hard nofile 65535
soft:使用者可自行調整的上限 (≤ hard)。hard:唯有 root 可提高的天花板。* 代表所有使用者;生效需重新登入或重啟。同步檢查 /etc/pam.d/common-session (Debian/Ubuntu) 或 /etc/pam.d/login (CentOS/RHEL) 是否包含:
session required pam_limits.so
/etc/sysctl.conf)fs.file-max = 2097152
fs.nr_open = 2097152 # 核心 2.4+ 單進程上限
sysctl -p # 立即套用
編輯服務單元 (如 /etc/systemd/system/nginx.service.d/limits.conf):
[Service]
LimitNOFILE=65535
LimitNPROC=65535
systemctl daemon-reload
systemctl restart nginx
# /etc/sysctl.d/99-tcp-tuning.conf
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_syn_backlog = 8192
net.core.somaxconn = 65535
sysctl --system
# 以目標使用者身份開新 Shell
ulimit -n
# 應顯示 65535
# 啟動服務後檢查
lsof -p $(pgrep -f java) | wc -l
# 應能超過 4000 不報錯
su - user 會重新讀取 limits.conf,但 sudo cmd 預設重置環境,需在 /etc/sudoers 加入 Defaults>user env_keep += "LIMITS" 或改用 systemd 管理。/etc/rc.local 已棄用:勿在其中放 ulimit,改用上述 systemd 或 limits.conf。--ulimit nofile=1024:4096,需在 docker run 或 docker-compose.yml 額外指定。依據環境依序套用上述層級,即可徹底根除「Too many open files」困擾。
修復 Vsftpd 上傳錯誤 553 Could not create file 的 SELinux 布林值設定
Linux 磁碟故障導致系統運行緩慢?排查 RAID 快取電池失效案例實錄
Linux 調整 TCP 本地端口範圍解決佔用衝突:ip_local_port_range 參數實戰
Linux 串口通訊工具 minicom 安裝與配置完整步驟
Linux 誤刪 root 使用者?用安裝光碟救援模式恢復 root 帳號與密碼
Ubuntu 32/64 位元安裝 Kid3 音樂標籤編輯器完整指令