4人参与 • 2026-08-06 • Linux
| 项目 | 说明 |
|---|---|
| 适用系统 | ubuntu 24.04 lts(也适用于其他 linux 发行版) |
| 适用服务 | nacos、zookeeper、kafka、elasticsearch、tomcat 等所有 java 中间件 |
| 配置目的 | 提高系统资源限制,避免高并发下 too many open files 或 unable to create new native thread 错误 |
linux 系统对资源的限制分为三个层级,必须全部配置才能确保生产环境稳定运行:
| 层级 | 限制项 | 作用范围 | 高并发时的报错 |
|---|---|---|---|
| 系统级 | fs.file-max | 整个操作系统所有进程总共能打开的文件数 | too many open files in system |
| 系统级 | kernel.pid_max | 整个操作系统总共能创建的进程/线程数 | fork: cannot allocate memory |
| 用户/进程级 | nofile(软/硬) | 单个进程能打开的文件数 | too many open files |
| 用户/进程级 | nproc(软/硬) | 单个用户能拥有的进程/线程总数 | unable to create new native thread |
核心原则:系统级限制必须大于用户/进程级限制,否则后者的配置无法生效。三者构成完整的限制链条。
| 参数 | 含义 | 推荐值 | 说明 |
|---|---|---|---|
fs.file-max | 系统所有进程可打开的文件描述符总数 | 1000000 | 约每 1mb 内存支持 100 个句柄 |
kernel.pid_max | 系统可分配的 pid(进程/线程)总数 | 4194304 | 现代 linux 默认已提升,此值更稳妥 |
/etc/sysctl.d/ 目录下的配置文件按字典序加载,数字前缀越小越先加载,后加载的文件会覆盖先加载的文件中的同名参数。
加载顺序示例:
| 文件 | 加载顺序 | 参数值 | 最终生效 |
|---|---|---|---|
/etc/sysctl.d/10-network.conf | 第1个 | net.ipv4.tcp_syncookies = 1 | 保留 |
/etc/sysctl.d/50-default.conf | 第2个 | kernel.pid_max = 32768 | 被覆盖 |
/etc/sysctl.d/99-sysctl.conf | 第3个 | kernel.pid_max = 65535 | 被覆盖 |
/etc/sysctl.d/100-custom.conf | 第4个 | kernel.pid_max = 4194304 | ✅ 最终生效 |
为什么使用 100- 前缀?
/etc/sysctl.d/99-sysctl.conf,其中可能包含 kernel.pid_max = 65535。100-custom.conf(数字更大)可确保自定义配置在系统默认配置之后加载,从而覆盖默认值。sudo vim /etc/sysctl.d/100-custom.conf
写入以下内容:
# 系统总文件描述符上限 fs.file-max = 1000000 # 系统总 pid 上限(进程/线程) kernel.pid_max = 4194304
使配置立即生效:
sudo sysctl -p /etc/sysctl.d/100-custom.conf
或应用所有配置文件:
sudo sysctl --system
验证配置是否生效:
cat /proc/sys/fs/file-max cat /proc/sys/kernel/pid_max
预期输出:
1000000 4194304
如果发现参数值不符合预期,可查看加载顺序和来源:
sudo sysctl --system 2>&1 | grep -e "file-max|pid_max"
输出示例:
* applying /etc/sysctl.d/99-sysctl.conf ... kernel.pid_max = 65535 * applying /etc/sysctl.d/100-custom.conf ... kernel.pid_max = 4194304
如需撤销,删除或重命名文件(如 mv 100-custom.conf 100-custom.conf.bak),然后执行 sudo sysctl --system 重新加载。
| 概念 | 说明 |
|---|---|
| 软限制(soft) | 当前生效的限制值,进程可主动调整(不得超过硬限制) |
| 硬限制(hard) | 软限制的上限,由 root 设置,普通用户无法超越 |
关键结论:生产环境必须同时配置以下三个层面,形成完整的限制链条。
| 配置方法 | 生效对象 | 是否必须 | 原因 |
|---|---|---|---|
| 方法1:/etc/security/limits.conf | 登录会话(ssh/控制台) | ✅ 必须 | systemd 服务不读取此文件 |
| 方法2:/etc/systemd/system.conf | 所有 systemd 服务(全局默认) | ✅ 必须 | ssh 登录不读取此文件 |
| 方法3:服务单元文件 | 单个 systemd 服务(覆盖) | ❌ 按需 | 仅为特定服务设不同值时使用 |
注意:方法1 和 方法2 不是二选一,而是必须同时配置。方法3 仅在需要为特定服务设置**不同(更高或更低)**限制时使用。
| 场景 | nofile 软/硬 | nproc 软/硬 | 适用服务 |
|---|---|---|---|
| 通用中间件 | 65535 / 65535 | 65535 / 65535 | zookeeper、tomcat、spring boot |
| 高连接服务 | 1048576 / 1048576 | 65535 / 65535 | nacos 2.x、kafka、elasticsearch |
| redis / 数据库 | 65535 / 65535 | unlimited / unlimited | redis、mysql(不推荐 unlimited) |
建议:nproc 不建议设为 unlimited,统一使用 65535 更安全。
影响通过 ssh 登录或控制台直接登录的用户环境。
sudo vim /etc/security/limits.conf
在文件末尾添加:
# ============================================ # 文件描述符限制(nofile) # ============================================ # 所有用户通用配置(65535) * soft nofile 65535 * hard nofile 65535 # 针对高负载服务用户(1048576,需已创建专用用户) zookeeper soft nofile 1048576 zookeeper hard nofile 1048576 nacos soft nofile 1048576 nacos hard nofile 1048576 # ============================================ # 进程/线程数限制(nproc) # ============================================ # 所有用户通用配置 * soft nproc 65535 * hard nproc 65535 # 针对高负载服务用户 zookeeper soft nproc 65535 zookeeper hard nproc 65535 nacos soft nproc 65535 nacos hard nproc 65535
使配置生效:
# 需要重新登录 ssh 才能生效 exit # 重新连接后验证 ulimit -n # 查看 nofile ulimit -u # 查看 nproc
这是最关键的一步。如果不配置,所有 systemd 启动的服务都会无视 /etc/security/limits.conf。
sudo vim /etc/systemd/system.conf
取消注释并修改:
# ============================================ # 文件描述符限制 # ============================================ # ⚠️ 注意:不可设为 软:硬 不同值(如 1024:524288) # 这会导致 java 进程继承过低的软限制 # ✅ 正确写法:统一设为同一值 defaultlimitnofile=65535 # ============================================ # 进程/线程数限制 # ============================================ defaultlimitnproc=65535
同时修改用户级 systemd 配置:
sudo vim /etc/systemd/user.conf
同样修改:
defaultlimitnofile=65535 defaultlimitnproc=65535
使配置生效:
# 重新加载 systemd 进程配置 sudo systemctl daemon-reexec
建议:执行 daemon-reexec 后,重启服务器以确保所有已运行服务继承新配置。
对于 nacos、kafka 等需要更高限制的服务,在各自的 systemd 单元文件中单独覆盖。
sudo vim /etc/systemd/system/nacos.service
在 [service] 块中添加:
[service] limitnofile=1048576 limitnproc=65535
sudo systemctl daemon-reload sudo systemctl restart nacos
何时使用方法3:
| 场景 | 是否使用 |
|---|---|
所有服务统一用 65535 | ❌ 不需要 |
nacos 需 1048576,其他服务保持 65535 | ✅ 使用 |
| 临时测试某个服务需更高的限制 | ✅ 使用 |
| 为某个服务设置更低的限制(隔离风险) | ✅ 使用 |
| 优先级 | 配置来源 | 适用对象 | 是否必须 |
|---|---|---|---|
| 1(最高) | 服务单元文件 limitnofile= | 单个 systemd 服务 | ❌ 按需 |
| 2(中) | /etc/systemd/system.conf | 所有 systemd 服务 | ✅ 必须 |
| 3(低) | /etc/security/limits.conf | 登录会话(ssh/控制台) | ✅ 必须 |
| 默认值 | systemd/内核编译默认 | 无任何配置时 | — |
配置生效范围总结:
| 配置场景 | systemd 服务 | ssh/控制台登录 |
|---|---|---|
只配置方法1(limits.conf) | ❌ 不生效 | ✅ 生效 |
只配置方法2(system.conf) | ✅ 生效 | ❌ 不生效 |
| 配置方法1 + 方法2(✅ 推荐) | ✅ 生效 | ✅ 生效 |
| 配置方法1 + 方法2 + 方法3 | ✅ 生效(特定服务覆盖) | ✅ 生效 |
cat /proc/sys/fs/file-max cat /proc/sys/kernel/pid_max
ulimit -n # nofile ulimit -u # nproc
# 查看 nacos 进程 cat /proc/$(pgrep -f nacos)/limits | grep -e "max open files|max processes" # 查看 zookeeper 进程 cat /proc/$(pgrep -f zookeeper)/limits | grep -e "max open files|max processes"
预期输出:
max open files 1048576 1048576 files
max processes 65535 65535 processes
#!/bin/bash
echo "========== 系统级内核参数 =========="
echo "fs.file-max: $(cat /proc/sys/fs/file-max)"
echo "kernel.pid_max: $(cat /proc/sys/kernel/pid_max)"
echo ""
echo "========== 当前会话限制 =========="
echo "nofile (soft): $(ulimit -n)"
echo "nproc (soft): $(ulimit -u)"
echo ""
echo "========== 运行中 java 服务限制 =========="
for pid in $(pgrep -f "java"); do
name=$(cat /proc/$pid/cmdline | tr '\0' ' ' | cut -c1-50)
echo "pid: $pid ($name...)"
cat /proc/$pid/limits | grep -e "max open files|max processes" | sed 's/^/ /'
echo ""
done
保存为 verify-limits.sh 并执行:
chmod +x verify-limits.sh ./verify-limits.sh
| 文件路径 | 需修改的配置项 | 推荐值 | 是否必须 |
|---|---|---|---|
/etc/sysctl.d/100-custom.conf | fs.file-max | 1000000 | ✅ 必须 |
/etc/sysctl.d/100-custom.conf | kernel.pid_max | 4194304 | ✅ 必须 |
/etc/security/limits.conf | * soft/hard nofile/nproc | 65535 | ✅ 必须 |
/etc/systemd/system.conf | defaultlimitnofile | 65535 | ✅ 必须 |
/etc/systemd/user.conf | defaultlimitnproc | 65535 | ✅ 必须 |
/etc/systemd/system/nacos.service | limitnofile | 1048576 | ❌ 按需 |
/etc/systemd/system/zookeeper.service | limitnofile | 65535 | ❌ 按需 |
#!/bin/bash set -e echo "=== 配置系统资源限制(完整版)===" # ============================================ # 1. 系统级内核参数 # ============================================ echo "配置 /etc/sysctl.d/100-custom.conf..." sudo tee /etc/sysctl.d/100-custom.conf << 'eof' # 系统总文件描述符上限 fs.file-max = 1000000 # 系统总 pid 上限(进程/线程) kernel.pid_max = 4194304 eof sudo sysctl -p /etc/sysctl.d/100-custom.conf # ============================================ # 2. 用户/会话级限制 # ============================================ echo "配置 /etc/security/limits.conf..." sudo tee -a /etc/security/limits.conf << 'eof' # 生产环境资源限制配置 * soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535 # 高负载服务专用 zookeeper soft nofile 1048576 zookeeper hard nofile 1048576 nacos soft nofile 1048576 nacos hard nofile 1048576 zookeeper soft nproc 65535 zookeeper hard nproc 65535 nacos soft nproc 65535 nacos hard nproc 65535 eof # ============================================ # 3. systemd 服务全局默认值 # ============================================ echo "配置 /etc/systemd/system.conf..." sudo sed -i 's/^#defaultlimitnofile=/defaultlimitnofile=65535/' /etc/systemd/system.conf sudo sed -i 's/^#defaultlimitnproc=/defaultlimitnproc=65535/' /etc/systemd/system.conf echo "配置 /etc/systemd/user.conf..." sudo sed -i 's/^#defaultlimitnofile=/defaultlimitnofile=65535/' /etc/systemd/user.conf sudo sed -i 's/^#defaultlimitnproc=/defaultlimitnproc=65535/' /etc/systemd/user.conf # ============================================ # 4. 重载 systemd # ============================================ sudo systemctl daemon-reexec echo "" echo "=== 配置完成 ===" echo "请执行以下操作:" echo "1. 重新登录 ssh:exit 后再登录" echo "2. 重启 systemd 管理的服务(如 nacos、zookeeper)" echo "3. 执行 'ulimit -n' 验证当前会话" echo "4. 执行 'cat /proc/sys/fs/file-max' 验证内核参数"
保存为 configure-limits.sh 并执行:
chmod +x configure-limits.sh sudo ./configure-limits.sh
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
ulimit -n 显示 1024 | 未重新登录或方法1未配置 | 重新 ssh 登录,检查 /etc/security/limits.conf |
systemd 服务仍显示 1024 | 未配置 /etc/systemd/system.conf | 配置方法2,执行 systemctl daemon-reexec |
服务显示 1048576 但实际不够 | 单元文件中设置了较小值 | 检查方法3是否覆盖了 limitnofile=1024 |
| 修改后重启服务器仍不生效 | systemd 配置文件格式错误 | 检查是否误写了 1024:524288 等软硬不同格式 |
fs.file-max 修改后不生效 | 配置路径错误或未执行 sysctl -p | 检查 /etc/sysctl.d/ 下文件是否以 .conf 结尾 |
cat /proc/sys/fs/file-max 显示旧值 | 配置未加载或文件顺序冲突 | 执行 sudo sysctl --system 查看加载日志 |
nproc 对 root 不生效 | nproc 限制对 root 用户无效 | 生产服务不要用 root 运行 |
| 多个文件设置同一参数,最终值不对 | 文件加载顺序导致覆盖 | 检查 ls /etc/sysctl.d/*.conf,确认数字前缀最大文件包含目标配置 |
┌─────────────────────────────────────────────────────────────────┐
│ 系统级内核参数 │
│ /etc/sysctl.d/100-custom.conf │
│ fs.file-max = 1000000 ← 系统总文件描述符上限 │
│ kernel.pid_max = 4194304 ← 系统总 pid 上限 │
│ (100- 前缀确保在 99-sysctl.conf 之后加载,覆盖默认值) │
└─────────────────────────────────────────────────────────────────┘
│
│ 必须大于所有用户级限制
▼
┌─────────────────────────────────────────────────────────────────┐
│ 用户/进程级限制 │
├─────────────────────────────┬───────────────────────────────────┤
│ 方法1:limits.conf │ 方法2:systemd 全局 │
│ ssh/控制台登录生效 │ systemd 服务生效 │
│ * soft nofile 65535 │ defaultlimitnofile=65535 │
│ * hard nofile 65535 │ defaultlimitnproc=65535 │
│ * soft nproc 65535 │ │
│ * hard nproc 65535 │ │
├─────────────────────────────┴───────────────────────────────────┤
│ 方法3:服务单元文件(按需覆盖) │
│ [service] │
│ limitnofile=1048576 ← 仅高负载服务使用 │
│ limitnproc=65535 │
└────────────────────────────────────────────────────────────────┘
以上就是linux中生产环境系统资源限制的完整配置指南的详细内容,更多关于linux系统资源限制的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论