Linux句柄数优化命令步骤

Linux 文件句柄数优化完整步骤(ulimit + sysctl)

文件句柄(file descriptor):进程打开文件、socket、管道都占用句柄。默认值偏小,高并发服务(Java、Nginx、数据库、后端服务)容易报 too many open files
分为用户级限制(ulimit)系统全局限制(sysctl)

常见坑总结

  1. 改了 limits.conf,但是用 systemd 启动的程序不生效 → 需要改 service 的 LimitNOFILE
  2. ulimit -n 生效,但进程实际还是旧值 → 服务没有重启,进程不会自动刷新限制
  3. fs.nr_open < limits.conf hard nofile → 内核阻止,进程无法拉起
  4. 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 "脚本执行完成"

使用方法

  1. 保存为 optimize_fd.sh
  2. 授权:chmod +x optimize_fd.sh
  3. 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
posted @ 2026-09-10 16:03  锅巴编程  阅读(5)  评论(0)    收藏  举报