基于systemd的系统负载控制与检测方案
#作者:程宏斌
文章目录
- 1.服务架构
- 2.负载生成服务(load-generator)
- 3.资源监控服务(resource_monitor)
该方案由两个systemd服务组成,分别负责资源拉升和资源监控,实现CPU与内存使用率的动态调控。
1.服务架构
load-generator.service
用于在系统资源空闲时主动拉高CPU和内存使用率,确保资源利用率不低于设定值。
resource_monitor.service
用于实时监控系统CPU、内存使用率,并根据阈值自动启动或停止load-generator.service。
工作流程
resource_monitor.service周期性运行check_resource.sh,采集CPU和内存使用率。
如果任一使用率≥70%,就会检查load-generator.service是否运行:
运行中→停止服务,释放资源。
未运行→不做任何处理。
如果CPU和内存使用率均≤40%:
未运行→启动load-generator.service,拉高资源占用。
已运行→不做处理。
load-generator.service运行时调用load_generator.sh,持续占用CPU和内存(可按配置调整占用量)。

2.负载生成服务(load-generator)
脚本:load_generator.sh
存放路径:/usr/local/bin/load_generator.sh
示例配置:
CPU_CORES=KaTeX parse error: Expected 'EOF', got '#' at position 8: (nproc)#̲获取CPU核心数 RESERV…((CPU_CORES / 2))#保留空闲一半核心数
MEMORY_PERCENT=50#占用物理内存百分比
脚本内容:
#!/bin/bash
# 持续 CPU + 内存造压脚本
# Author: hongbinCPU_CORES=$(nproc) # CPU核心数
RESERVE_CPU=$((CPU_CORES - 2)) # 保留几个核心空闲
MEMORY_PERCENT=40 # 占用物理内存百分比(避免OOM)
MEM_BLOCK_SIZE=1M # 每个内存块大小
LOG_FILE="/var/log/load_generator.log"pids=() # 存储CPU压测进程PID
memfile="/tmp/memory_stress/block"start_load() {echo "$(date '+%F %T') 启动CPU+内存造压" | tee -a "$LOG_FILE" > /dev/null 2>&1 # ===== CPU造压 =====free_cpu=$((CPU_CORES - RESERVE_CPU))[ "$free_cpu" -lt 1 ] && free_cpu=1for i in $(seq 0 $((free_cpu-1))); donohup taskset -c $i yes > /dev/null 2>&1 &pids+=($!)done# ===== 内存造压 =====mkdir -p /tmp/memory_stressumount /tmp/memory_stress 2>/dev/nullmount -t tmpfs -o size=${MEMORY_PERCENT}% tmpfs /tmp/memory_stress# 占用内存dd if=/dev/zero of="$memfile" bs=$MEM_BLOCK_SIZE count=$((MEMORY_PERCENT*$(free -m | awk '/Mem:/{print $2}')/100)) status=none &pids+=($!)
}stop_load() {exec 2> /dev/nullecho "$(date '+%F %T') 停止CPU+内存造压" | tee -a "$LOG_FILE" > /dev/null 2>&1for pid in "${pids[@]}"; dokill -9 "$pid" > /dev/null 2>&1doneumount /tmp/memory_stress > /dev/null 2>&1rm -rf /tmp/memory_stress > /dev/null 2>&1pids=()
}trap stop_load EXITwhile true; dostart_loadsleep infinity & wait
done
功能:
检测系统资源使用情况(可在脚本内自行配置阈值)
当资源低于设定值时,占用指定数量CPU核心与内存
避免OOM(内存溢出)风险
服务文件:/etc/systemd/system/load-generator.service
示例配置:
[Unit]
Description=CPU+MemoryStressGenerator
After=network.target[Service]
Type=simple
ExecStart=/usr/local/bin/load_generator.sh
Restart=always
RestartSec=3
LimitNOFILE=65535[Install]
WantedBy=multi-user.target
3.资源监控服务(resource_monitor)
脚本:check_resource.sh
存放路径:/usr/local/bin/check_resource.sh
示例配置:
LOW_THRESHOLD=40#低于此值启动负载服务
HIGH_THRESHOLD=70#高于此值停止负载服务
logfile=“/var/log/check_resource.log”
脚本内容:
#!/bin/bashLOW_THRESHOLD=40
HIGH_THRESHOLD=70
logfile="/var/log/check_resource.log"while true; do# ===== CPU 使用率计算 =====cpu_line1=($(head -n1 /proc/stat))sleep 1cpu_line2=($(head -n1 /proc/stat))user=$((cpu_line2[1] - cpu_line1[1]))nice_value=$((cpu_line2[2] - cpu_line1[2]))system=$((cpu_line2[3] - cpu_line1[3]))idle=$((cpu_line2[4] - cpu_line1[4]))iowait=$((cpu_line2[5] - cpu_line1[5]))irq=$((cpu_line2[6] - cpu_line1[6]))softirq=$((cpu_line2[7] - cpu_line1[7]))total=$((user + nice_value + system + idle + iowait + irq + softirq))busy=$((total - idle - iowait))cpu_usage=$((busy * 100 / total))# ===== 内存使用率 =====mem_usage=$(free | awk '/Mem:/ {printf("%.0f", $3/$2*100)}')echo "$(date) CPU使用率: ${cpu_usage}%, 内存使用率: ${mem_usage}%" >> "$logfile"# ===== 判断逻辑 =====if [ "$cpu_usage" -ge "$HIGH_THRESHOLD" ] || [ "$mem_usage" -ge "$HIGH_THRESHOLD" ]; then# 高于高阈值 → 停止造压服务if systemctl is-active --quiet load-generator.service; thenecho "$(date) 资源使用≥${HIGH_THRESHOLD}%,停止 load-generator.service" >> "$logfile"systemctl stop load-generator.servicefielif [ "$cpu_usage" -lt "$LOW_THRESHOLD" ] && [ "$mem_usage" -lt "$LOW_THRESHOLD" ]; then# 同时低于低阈值 → 启动造压服务if ! systemctl is-active --quiet load-generator.service; thenecho "$(date) 资源使用<${LOW_THRESHOLD}%,启动 load-generator.service" >> "$logfile"systemctl start load-generator.servicefielse# 在 40%~70% 之间 → 不操作echo "$(date) 资源在${LOW_THRESHOLD}%~${HIGH_THRESHOLD}%之间,保持现状" >> "$logfile"fisleep 10
done
功能:
定时检查CPU与内存使用率
当资源使用率高于设定上限,停止load-generator.service
当资源使用率低于设定下限,启动load-generator.service
服务文件:/etc/systemd/system/resource_monitor.service
示例配置:
[Unit]
Description=ResourceMonitorServicetoControlLoadGenerator
After=network.target[Service]
Type=simple
ExecStart=/usr/local/bin/check_resource.sh
Restart=always
RestartSec=5[Install]
WantedBy=multi-user.target
