如何可靠监控Linux系统中的CPU饥饿现象?
可靠监控Linux CPU「饥饿」状态的方法
要避免轮询/proc/stat时错过procs_running超过在线CPU数的事件,可采用以下几种内核级或高频监控方案:
1. eBPF 实时跟踪(最可靠)
eBPF 能在内核态植入钩子,实时捕捉调度器事件并判断可运行进程数是否超标,完全不会遗漏瞬间峰值。
例如用 bpftrace 编写脚本,监听调度器唤醒/切换事件,实时统计可运行进程数并触发告警:
BEGIN { @online_cpus = nr_online_cpus(); printf("开始监控:当procs_running > %d时触发告警\n", @online_cpus); } # 监听进程唤醒和调度切换事件,每次事件触发时检查 tracepoint:sched:sched_wakeup, tracepoint:sched:sched_switch { # 读取/proc/stat中的procs_running值 $stat = file_read("/proc/stat"); @procs_running = strtol($stat, "procs_running "); if (@procs_running > @online_cpus) { time("%Y-%m-%d %H:%M:%S "); printf("CPU饥饿触发:procs_running = %d,超过在线CPU数 %d\n", @procs_running, @online_cpus); } }
执行脚本后,只要调度器有状态变化就会检查阈值,完全覆盖所有可能的峰值时刻。
2. 内核 ftrace 跟踪
ftrace 是内核自带的跟踪框架,可通过调度器事件(如sched_switch、sched_wakeup)实时监控进程状态变化,再通过用户态工具分析:
- 开启ftrace跟踪:
trace-cmd record -e sched_switch -e sched_wakeup - 同时编写脚本实时解析
trace-cmd show的输出,统计当前可运行进程数,当超过CPU数量时触发告警。这种方法无需额外安装eBPF工具,依赖内核原生功能。
3. 高频轮询(简单易行)
如果无法使用内核级跟踪,可缩短轮询间隔至100ms甚至更短,结合峰值记录降低遗漏概率。例如用bash+awk实现高频采样:
#!/bin/bash ONLINE_CPUS=$(nproc) while true; do PROCS_RUNNING=$(grep -oP 'procs_running \K\d+' /proc/stat) if [ "$PROCS_RUNNING" -gt "$ONLINE_CPUS" ]; then echo "$(date +'%Y-%m-%d %H:%M:%S') - CPU饥饿:procs_running=$PROCS_RUNNING > $ONLINE_CPUS" fi usleep 100000 # 100ms间隔 done
虽然仍存在理论上的遗漏可能,但对于绝大多数场景,100ms的间隔已足够捕捉短暂的CPU饥饿事件。
内容的提问来源于stack exchange,提问作者Kamil Zaripov
相关产品推荐
相关产品推荐

