Linux句柄数优化命令步骤
Linux 文件句柄数优化完整步骤(ulimit + sysctl)
文件句柄(file descriptor):进程打开文件、socket、管道都占用句柄。默认值偏小,高并发服务(Java、Nginx、数据库、后端服务)容易报
too many open files。
分为用户级限制(ulimit) 和系统全局限制(sysctl)
常见坑总结
- 改了 limits.conf,但是用 systemd 启动的程序不生效 → 需要改 service 的 LimitNOFILE
- ulimit -n 生效,但进程实际还是旧值 → 服务没有重启,进程不会自动刷新限制
- fs.nr_open < limits.conf hard nofile → 内核阻止,进程无法拉起
- lsof 统计数量会大于 file-max:lsof 包含内核预留,file-max 是用户进程可用上限
Linux 文件句柄一键优化脚本
#!/bin/bash
# Linux 文件句柄数一键优化脚本
# 需root执行
set -e
if [ "$(id -u)" -ne 0 ];then
echo "❌ 请使用root用户执行脚本"
exit 1
fi
# ===================== 配置项,按需修改 =====================
SOFT_NOFILE=65535
HARD_NOFILE=65535
SYS_FILE_MAX=655350
SYS_NR_OPEN=655350
# ==========================================================
echo "==================== 优化前现状 ===================="
echo "当前shell ulimit -n: $(ulimit -n)"
echo "fs.file-max: $(cat /proc/sys/fs/file-max)"
echo "fs.nr_open: $(cat /proc/sys/fs/nr_open)"
echo "已使用句柄(file-nr): $(cat /proc/sys/fs/file-nr)"
echo ""
# 1. 修改 /etc/security/limits.conf
LIMITS_CONF="/etc/security/limits.conf"
# 清除旧的* nofile配置,追加新配置
sed -i '/^\*.*nofile/d' ${LIMITS_CONF}
sed -i '/^root.*nofile/d' ${LIMITS_CONF}
cat >> ${LIMITS_CONF} <<EOF
* soft nofile ${SOFT_NOFILE}
* hard nofile ${HARD_NOFILE}
root soft nofile ${SOFT_NOFILE}
root hard nofile ${HARD_NOFILE}
EOF
echo "✅ 已更新 ${LIMITS_CONF}"
# 2. 修改sysctl.conf
SYSCTL_CONF="/etc/sysctl.conf"
sed -i '/^fs.file-max/d' ${SYSCTL_CONF}
sed -i '/^fs.nr_open/d' ${SYSCTL_CONF}
cat >> ${SYSCTL_CONF} <<EOF
fs.file-max = ${SYS_FILE_MAX}
fs.nr_open = ${SYS_NR_OPEN}
EOF
# 加载sysctl配置
sysctl -p >/dev/null
echo "✅ sysctl配置已加载"
# 临时修改当前会话ulimit
ulimit -n ${HARD_NOFILE}
echo "✅ 当前会话临时ulimit设置为 ${HARD_NOFILE}"
echo ""
echo "==================== 优化后校验 ===================="
echo "当前shell ulimit -n: $(ulimit -n)"
echo "fs.file-max: $(cat /proc/sys/fs/file-max)"
echo "fs.nr_open: $(cat /proc/sys/fs/nr_open)"
echo ""
echo "⚠️重要提示:"
echo "1. limits.conf 需要【重新登录SSH】才会永久生效,当前shell只是临时生效"
echo "2. systemd托管服务(Nginx/Java等),limits.conf不生效!必须在service [Service]段添加 LimitNOFILE=${HARD_NOFILE}"
echo "3. 添加后执行:systemctl daemon‑reload && restart 你的服务"
echo "4. 校验进程真实限制:cat /proc/<PID>/limits"
echo ""
echo "脚本执行完成"
使用方法
- 保存为
optimize_fd.sh - 授权:
chmod +x optimize_fd.sh - root 执行:
./optimize_fd.sh
systemd 服务配置片段示例(手动加进 xxx.service)
[Service]
LimitNOFILE=65535
systemctl daemon-reload
systemctl restart 你的服务名
# 校验
cat /proc/$(pidof java)/limits
高并发场景调大示例
如果你是网关、IM 服务,直接修改脚本顶部变量:
SOFT_NOFILE=1048576
HARD_NOFILE=1048576
SYS_FILE_MAX=2097152
SYS_NR_OPEN=2097152

浙公网安备 33010602011771号