Linux 系統預設的資源限制 (如最大打開文件數 open files、最大進程數 max user processes) 往往無法滿足高併發服務 (Nginx、Java、MySQL、Redis 等) 的需求,導致「Too many open files」或「Unable to create new native thread」錯誤。本文詳細說明如何查看、臨時修改、永久調優這些關鍵限制參數。
使用 ulimit -a 查看所有資源限制:
[root@host ~]# 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) 54652
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024 # 關鍵:最大打開文件描述符數
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
max user processes (-u) 54652 # 關鍵:最大用戶進程/線程數
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
重點關注:open files (-n) 預設 1024 過小;max user processes (-u) 可能受限。
# 修改最大打開文件數為 65535
ulimit -n 65535
# 修改最大用戶進程數
ulimit -u 65535
# 驗證
ulimit -n
ulimit -u
缺點:重啟終端或重啟服務後失效,不適合生產環境服務啟動腳本。
/etc/security/limits.conf (推薦,PAM 機制)vim /etc/security/limits.conf
# 文件末尾添加 (針對所有用戶 *,或指定用戶如 www、mysql):
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
# 針對 root 用戶 (某些發行版 root 不受 * 限制)
root soft nofile 65535
root hard nofile 65535
root soft nproc 65535
root hard nproc 65535
說明:soft 為當前生效上限,用戶可用 ulimit 在此範圍內調大;hard 為系統絕對上限,只有 root 可提高。兩者通常設為同值。
/etc/profile 或用戶 ~/.bash_profile (舊式,不推薦)echo "ulimit -n 65535" >> /etc/profile
echo "ulimit -u 65535" >> /etc/profile
source /etc/profile
此法依賴 Shell 登入讀取,非登入 Shell (如 systemd 啟動服務) 可能不生效。
檢查 /etc/pam.d/login、/etc/pam.d/sshd、/etc/pam.d/su 等文件包含:
session required pam_limits.so
大多數現代發行版預設已包含。
對於由 Systemd 管理的服務 (Nginx、Docker、Java 應用等),不受 limits.conf 控制,需在服務單元文件中設置:
# 編輯服務單元 (如 nginx.service)
systemctl edit nginx.service
# 或直接修改 /usr/lib/systemd/system/nginx.service
# 在 [Service] 區塊添加:
[Service]
LimitNOFILE=65535
LimitNPROC=65535
# LimitMEMLOCK=infinity # 如需鎖定內存 (Elasticsearch等)
# 重載並重啟
systemctl daemon-reload
systemctl restart nginx
僅調大 ulimit 不夠,內核網絡棧、文件表也需擴容:
vim /etc/sysctl.conf
# 文件系統級最大打開文件數 (系統全域)
fs.file-max = 1000000
# TCP 連接追蹤表大小 (防連接丟失)
net.netfilter.nf_conntrack_max = 1000000
net.netfilter.nf_conntrack_tcp_timeout_established = 1200
# 套接字緩衝區優化
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# 生效
sysctl -p
ulimit -a 確認 open files 和 max user processes 已變為 65535。cat /proc/$(pgrep -o nginx)/limitsMax open files 和 Max processes 行。/etc/security/limits.conf 設置 nofile/nproc。LimitNOFILE/LimitNPROC。/etc/sysctl.conf 擴容 fs.file-max、TCP 佇列等。65535 起步,極高併發可設 1000000 (需內核支援)。/proc/PID/limits。