Linux 系统资源负载控制脚本:CPU 内存一键管理(后台常驻版)
在日常性能测试、故障演练或容量评估中,我们经常需要人为地制造 CPU 或内存压力。本文将分享一个交互式、后台常驻的 Bash 脚本,支持:
- 30% / 40% / 50% / 60% / 80% / 100% 六档 CPU 负载
- 30% / 40% / 50% / 60% / 80% / 95% 六档内存占用
- 退出脚本后负载继续生效,重新运行脚本可随时调整或停止
- CPU 与内存控制完全解耦,互不影响
一、脚本功能速览
功能 | 快捷键 | 说明 |
---|---|---|
CPU 负载控制 | 1 → 30~99 | 按需生成 dd 进程 |
内存负载控制 | 2 → 30~99 | 在 /dev/shm 创建临时文件 |
停止所有负载 | 3 | 一键清理 CPU & 内存 |
退出脚本 | 0 | 负载仍保持运行 |
查看实时状态 | 主菜单顶部 | 显示当前百分比 + PID |
二、脚本代码
将以下内容保存为 resource_controller.sh
,chmod +x
后即可使用。
#!/bin/bash
# ------------------------------------------------------------
# Linux 资源负载控制器 - 后台常驻版
# Author: <your-name>
# ------------------------------------------------------------
PID_DIR="/tmp/resource_pids"
mkdir -p "$PID_DIR"# ---------- 菜单 ----------
show_menu() {clearecho "========================================="echo " Linux 资源负载控制中心 (后台常驻版)"echo "========================================="echo "1. CPU负载控制"echo "2. 内存负载控制"echo "3. 停止所有负载"echo "0. 退出脚本"echo "========================================="echo "[当前状态]"check_cpu_statuscheck_mem_statusecho "========================================="read -p "请选择操作 [0-3]: " main_choice
}cpu_menu() {echo "-----------------------------------------"echo "CPU 负载级别"echo "30 40 50 60 80 99(100%)"echo "0 停止 b 返回"read -p "级别: " cpu_choice
}mem_menu() {echo "-----------------------------------------"echo "内存 负载级别"echo "30 40 50 60 80 99(95%)"echo "0 停止 b 返回"read -p "级别: " mem_choice
}# ---------- 状态检查 ----------
check_cpu_status() {[[ -f "$PID_DIR/cpu.pid" ]] && ps -p $(<"$PID_DIR/cpu.pid") &>/dev/null \&& echo "CPU负载: 运行中 ($(ps -o cmd= -p $(<"$PID_DIR/cpu.pid") | awk -F'=' '{print $2}')%)" \|| echo "CPU负载: 未运行"
}check_mem_status() {[[ -f "$PID_DIR/mem.pid" ]] && ps -p $(<"$PID_DIR/mem.pid") &>/dev/null \&& echo "内存负载: 运行中" \|| echo "内存负载: 未运行"
}# ---------- 停止 ----------
stop_cpu_load() {[[ -f "$PID_DIR/cpu.pid" ]] && kill -9 $(<"$PID_DIR/cpu.pid") 2>/dev/nullrm -f "$PID_DIR/cpu.pid"pkill -f 'dd if=/dev/zero of=/dev/null' 2>/dev/null
}stop_mem_load() {[[ -f "$PID_DIR/mem.pid" ]] && kill -9 $(<"$PID_DIR/mem.pid") 2>/dev/nullrm -f "$PID_DIR/mem.pid"pkill -f 'dd if=/dev/zero of=/dev/shm/memload_' 2>/dev/nullrm -f /dev/shm/memload_*sync && echo 3 > /proc/sys/vm/drop_caches 2>/dev/null
}stop_all_load() {stop_cpu_loadstop_mem_loadecho "✅ 已停止所有负载"sleep 1
}# ---------- CPU ----------
start_cpu_load() {percent=$1core_count=$(nproc)count=$(( (core_count * percent + 5) / 10 ))stop_cpu_loadcat > /tmp/start_cpu_daemon.sh <<EOF
#!/bin/bash
echo \$\$ > "$PID_DIR/cpu.pid"
for ((i=0;i<$count;i++)); do dd if=/dev/zero of=/dev/null status=none & done
sleep infinity
EOFchmod +x /tmp/start_cpu_daemon.shnohup /tmp/start_cpu_daemon.sh >/dev/null 2>&1 &echo "✅ CPU负载${percent}%已启动 (${count}进程)"
}# ---------- 内存 ----------
start_mem_load() {percent=$1total_mb=$(( $(grep MemTotal /proc/meminfo | awk '{print $2}') / 1024 ))[[ $percent -eq 99 ]] && target=95 || target=$percenttarget_mb=$(( total_mb * target / 100 - 100 ))[[ $target_mb -lt 100 ]] && target_mb=100blocks=$((target_mb / 100))remainder=$((target_mb % 100))stop_mem_loadcat > /tmp/start_mem_daemon.sh <<EOF
#!/bin/bash
echo \$\$ > "$PID_DIR/mem.pid"
for ((i=1;i<=$blocks;i++)); do dd if=/dev/zero of=/dev/shm/memload_\${i}_\$\$ bs=100M count=1 status=none; done
[[ $remainder -gt 0 ]] && dd if=/dev/zero of=/dev/shm/memload_last_\$\$ bs=${remainder}M count=1 status=none
sleep infinity
EOFchmod +x /tmp/start_mem_daemon.shnohup /tmp/start_mem_daemon.sh >/dev/null 2>&1 &echo "✅ 内存负载${target}%已启动 (${target_mb}MB)"
}# ---------- 主循环 ----------
while true; doshow_menucase $main_choice in1)while true; docpu_menucase $cpu_choice in30|40|50|60|80|99) start_cpu_load $cpu_choice ;;0) stop_cpu_load ;;b|B) break ;;*) echo "无效选择"; sleep 1 ;;esacdone ;;2)while true; domem_menucase $mem_choice in30|40|50|60|80|99) start_mem_load $mem_choice ;;0) stop_mem_load ;;b|B) break ;;*) echo "无效选择"; sleep 1 ;;esacdone ;;3) stop_all_load ;;0) echo "脚本已退出,负载仍在后台"; exit 0 ;;*) echo "无效选择"; sleep 1 ;;esac
done
三、快速上手
- 赋权 & 启动
chmod +x resource_controller.sh./resource_controller.sh
操作示例
- 主菜单选
1
→60
→ CPU 负载 60% 立即生效 - 主菜单选
2
→80
→ 内存占用 80% 立即生效 - 选
0
退出脚本,负载不会停止 - 再次运行脚本可查看/调整/停止
- 主菜单选
验证效果
top -1 # 查看 CPU 占用free -m # 查看内存占用ls /dev/shm # 查看内存文件
四、技术要点
技术 | 用途 |
---|---|
nohup + sleep infinity | 实现后台常驻 |
/dev/shm 内存文件系统 | 制造内存占用不占用磁盘 |
PID_DIR 保存进程号 | 精确管理,避免误杀 |
dd if=/dev/zero | 简单可靠的负载生成器 |
drop_caches | 清理页缓存,立即释放内存 |
五、常见问题
脚本退出后负载消失? 确保使用
nohup
启动守护进程(已内置)。需要 root 吗? 普通用户即可,但
drop_caches
需 root,无 root 时会自动跳过。如何彻底清理? 重新运行脚本 → 选择
3
停止所有负载,或手动pkill dd
并删除/dev/shm/memload_*
。
六、扩展思路
- 定时任务:配合
cron
做周期性压测 - 远程触发:通过
ssh
调用脚本做分布式压测 - 监控集成:将负载百分比写入 Prometheus 指标
- 容器化:打包成镜像在 K8s 中做 Chaos 工程