RHEL系统“too many open files”错误复现与测试方案咨询
RHEL "too many open files" 错误复现测试方案
相关查询命令
- 操作系统级最大打开文件数限制:
cat /proc/sys/fs/file-max;当前系统已打开文件总数查看:cat /proc/sys/fs/file-nr(输出第一个值即为当前已打开总数) - 全局已打开文件数统计:
sudo lsof | wc -l,该统计结果包含重复值,仅供参考 - 单进程最大打开文件数限制:
ulimit -n,常规环境默认值为1024 - 指定进程已打开文件数统计:
sudo lsof -p <PID> | wc -l
单进程触发ulimit -n 限制测试
本测试用于复现单个进程超出自身打开文件数上限的场景,测试脚本逻辑为循环打开空测试文件,直到触发错误后保持进程运行,方便后续观测。
测试脚本内容如下:
#!/bin/bash # 创建测试用空文件 test_file="/tmp/test_open_file" touch ${test_file} # 计算需要打开的文件数:当前ulimit值 + 1,抵消进程默认打开的stdin/stdout/stderr三个文件描述符占用 max_fd=$(ulimit -n) target=$((max_fd + 1)) echo "当前进程ulimit -n 限制为 ${max_fd},尝试打开 ${target} 个文件..." declare -a fd_array for ((i=0; i<target; i++)) do # 分配文件描述符打开测试文件 exec {fd}<>${test_file} if [ $? -ne 0 ]; then echo "触发错误:too many open files,当前已打开文件数:${i}" # 保持进程不退出,维持已打开的文件描述符 sleep infinity fi fd_array+=(${fd}) done
执行方式:直接运行脚本即可,触发错误后可通过lsof -p <脚本进程PID> | wc -l验证进程打开的文件数是否与ulimit限制匹配。
多进程触发系统级file-max限制测试
注意:本测试会占用大量系统文件描述符,可能影响其他业务正常运行,仅建议在测试环境执行,操作前请先记录系统当前file-max值,预留运维操作空间。
本测试通过批量启动多个单进程测试脚本,每个进程占满自身ulimit打开文件数,最终触发系统级打开文件数上限。
批量启动脚本内容如下:
#!/bin/bash # 读取系统级最大打开文件数 system_max=$(cat /proc/sys/fs/file-max) # 读取当前系统已打开文件数 current_open=$(cat /proc/sys/fs/file-nr | awk '{print $1}') # 每个测试进程可占用的文件数 per_process_usage=$(($(ulimit -n) - 3)) # 计算需要启动的测试进程总数 need_process=$(( (system_max - current_open) / per_process_usage + 1 )) echo "系统file-max为 ${system_max},当前已打开 ${current_open},需要启动 ${need_process} 个测试进程" for ((i=0; i<need_process; i++)) do # 后台启动单进程测试脚本,请替换为你实际存放单进程脚本的路径 bash /opt/test/single_process_open_file.sh & echo "已启动第 ${i} 个测试进程,PID:$!" done
执行后可持续观测cat /proc/sys/fs/file-nr的输出,当第一个值接近file-max时,新的进程打开文件就会触发系统级的too many open files错误。
测试进程清理方案
测试完成后可通过以下方式一键清理所有测试进程,释放占用的文件描述符:
- 匹配sleep进程批量清理:
pkill -f "sleep infinity" - 匹配脚本名称批量清理:
pkill -f "single_process_open_file.sh" - 若上述命令不生效,可强制清理:
ps aux | grep "single_process_open_file.sh" | awk '{print $2}' | xargs kill -9
清理完成后执行cat /proc/sys/fs/file-nr确认已打开文件数回落到正常水平即可。
内容的提问来源于stack exchange,提问作者gaut
相关产品推荐
相关产品推荐

