Linux服务器卡顿之CPU性能全流程分析与落地实践
一、核心认知:CPU性能指标解读(避免踩坑)
排查前先理清关键指标含义,避免因指标混淆走弯路。核心数据可通过`top`/`uptime`直接获取,所有分析围绕以下指标展开。
1. 核心关键指标
指标 | 含义 | 异常判定 | 核心说明 |
%CPU(利用率) | 单位时间内CPU被占用比例,分用户态、内核态等子项 | 长期空闲率(id)<20% 视为瓶颈 | 重点看用户态(us)和内核态(sy),二者之和接近100%即为满负载 |
load average(系统负载) | 1/5/15分钟内等待运行的进程数(含CPU/IO等待) | 超过CPU逻辑核心数即为过高;15分钟负载持续高需重视 | 负载高≠CPU忙(比如IO卡顿时,CPU空闲但负载高) |
CPU核心数 | 物理核心/逻辑核心(超线程)数量 | 无绝对异常值,需结合负载判断 | 用`lscpu`查看,是判断负载是否过高的基准 |
st(虚拟化抢占) | 云服务器中宿主机抢占虚拟机CPU的比例 | st≥5% 视为异常 | 仅云服务器有效,高值需联系云厂商排查宿主机 |
2. 利用率细分字段解读(`top`输出核心)
`top`中%CPU(s)字段示例:`70 us, 20 sy, 5 id, 3 wa, 0 hi, 2 si, 0 st`,各子项含义及异常指向如下:
- us(用户态):业务进程(应用、数据库)消耗占比,us≥70%通常是业务代码/应用问题;
- sy(内核态):系统处理调用、调度、内存管理的消耗,sy≥30%需排查系统调用或内核线程异常;
- id(空闲率):CPU空闲比例,id<10%说明CPU资源紧张;
- wa(IO等待):CPU等磁盘/网络IO完成的时间,wa≥20%是IO瓶颈(不是CPU本身问题);
- si/hi(软/硬中断):软件/硬件中断消耗,si高可能是网络包风暴,hi高可能是硬件驱动异常;
- si/so(交换分区):内存不足时的换页消耗,si/so>0是内存瓶颈(伪CPU问题)。
3. 核心结论(快速判断瓶颈类型)
- us+sy≥90% 且 id≤10% → 纯CPU瓶颈(优化业务/内核逻辑);
- wa≥20% 或 si/so>0 → 伪CPU瓶颈(先解决IO/内存问题);
- sy≥30% 且 us较低 → 内核层问题(系统调用、调度、中断);
- 负载高但 id≥50% → 进程阻塞(锁竞争/IO等待),不是CPU性能不足。
二、全流程排查:从快速初判到精准定位
按“轻量初判→精准定位→深度析因”分步推进,优先用系统原生命令,无额外依赖,适合生产环境紧急排查。
1. 快速初判(30秒搞定是否为CPU瓶颈)
用无侵入、轻量工具快速判断瓶颈类型,排除伪CPU问题,明确后续排查方向。
工具/命令 | 核心操作 | 排查要点 | 快速结论 |
uptime | 直接执行,查看1/5/15分钟负载 | 对比`lscpu`获取的CPU逻辑核心数 | 负载>核心数→进程阻塞;15分钟负载上升→需紧急处理 |
top | 按P排序CPU、按1展开核心、按H显示线程 | us/sy/id/wa值、高CPU进程PID、核心利用率分布 | 单进程%CPU≈100%→进程异常;单核心满负载→多核利用不均 |
free -h | 查看内存及交换分区使用情况 | si/so是否>0,内存剩余是否充足 | si/so>0→先解决内存问题,再查CPU |
iostat -x 1 | 磁盘IO统计,1秒采样1次 | %util(磁盘利用率)、await(IO等待时间) | wa≥20%→IO瓶颈,先优化磁盘/网络IO |
2. 精准定位:从进程到线程再到核心
确认是纯CPU瓶颈后,逐步缩小范围,找到具体消耗CPU的进程、线程及核心。
(1)进程级定位:pidstat(精准统计)
弥补`top`瞬时值的不足,支持持续采样,适合跟踪高CPU进程变化。常用命令:
# 每1秒采样1次,共5次,查看所有进程CPU使用
pidstat -u 1 5
# 聚焦指定PID,查看其用户态/内核态占比
pidstat -u -p 1234 1 5
# 查看指定进程的所有线程CPU消耗(-t参数)
pidstat -u -t -p 1234 1 5 核心关注:%CPU(进程/线程总占用)、%usr/%sys(用户态/内核态占比)、TID(线程ID,后续分析用)。
(2)线程级定位:ps/top -H/pstack
高CPU消耗多是单个线程导致,需从进程中定位具体线程,步骤如下:
- 获取高CPU线程TID:`top -H -p 1234`(按P排序)或`ps -mp 1234 -o THREAD,tid,pcpu | sort -k3 -r`;
- TID转十六进制:`printf "%x\n" 5678`(jstack/pstack日志用十六进制标识线程);
- 查看线程调用栈:`pstack 1234 | grep -A 10 十六进制TID`,定位耗时函数。
(3)核心级定位:mpstat(排查多核不均)
专门统计单个CPU核心利用率,快速定位单核心瓶颈,命令:`mpstat -P ALL 1 5`,核心结论:
- 某核心us+sy≥90%,其他核心id≥80%→单线程程序/锁竞争导致多核利用不均;
- 所有核心负载均衡但整体id低→多线程计算密集型任务。
3. 深度析因:找到代码/内核级根因
定位到线程/核心后,进一步分析执行逻辑,找到代码行/函数级根因,按工具和语言场景处理。
(1)通用工具:perf(Linux性能分析神器)
内核自带工具,支持所有语言,可生成CPU火焰图(可视化调用链),精准定位高耗函数,步骤:
# 1. 安装perf(部分系统默认自带)
yum install -y perf / apt install -y linux-tools-common
# 2. 采样指定进程120秒,记录调用链(-g)
perf record -F 99 -p 1234 -g -o perf.data sleep 120
# 3. 生成火焰图(需下载火焰图脚本)
git clone https://github.com/brendangregg/FlameGraph.git
perf script -i perf.data > perf.script
./FlameGraph/stackcollapse-perf.pl perf.script > perf.folded
./FlameGraph/flamegraph.pl perf.folded > cpu-flame.svg 火焰图解读:横轴越宽表示CPU耗时越多,纵轴是函数调用链,点击可放大细节,红色区域为核心瓶颈函数。
(2)语言专属工具
- Java程序:用JDK自带`jstack`/`jstat`,或`arthas`(无侵入)。`jstack 1234 > jstack.log`抓线程栈,搜索十六进制TID定位死循环/锁竞争;`jstat -gc 1234 1 5`排查频繁GC问题;
- C/C++程序:`pstack`抓栈,`gdb -p 1234`调试,`bt`命令查看线程调用链,判断死循环/低效算法;
- Go程序:`go tool pprof http://IP:6060/debug/pprof/profile?seconds=10`采样,`top`命令查看高耗函数,`web`生成调用链图。
(3)内核态高(sy高)专项排查:strace
当sy≥30%时,用`strace`跟踪系统调用,定位频繁调用类型,命令:
# 统计指定进程的系统调用次数和耗时
strace -c -p 1234
# 实时查看进程的系统调用细节
strace -f -p 1234 核心关注:read/write(文件IO)、recv/send(网络IO)、fork/exec(进程创建)等调用的次数和耗时,高频调用即为内核态高的根因。
三、常见CPU瓶颈场景及根因分析
结合生产经验,按“用户态高、内核态高、伪瓶颈”分类,总结常见场景、指标特征及排查要点,快速对号入座。
1. 用户态高(us≥70%):业务/应用层问题
场景 | 指标特征 | 排查要点 | 临时解决 |
死循环/无限递归 | 单进程%CPU≈100%,us高,线程栈重复调用同一函数 | 用pstack/jstack查看线程栈,定位重复调用的业务函数 | 重启异常进程,备份日志后排查代码 |
低效算法(O(n²)) | 大数据量下us持续高,火焰图显示某算法函数占比极高 | 跟踪函数耗时,将低效算法优化为O(nlogn)(如哈希表、二分查找) | 临时限制数据量,避免触发低效逻辑 |
数据库慢查询 | mysqld进程%CPU高,show processlist显示大量Executing语句 | 用explain分析SQL,检查索引是否缺失、语句是否优化 | 杀死慢查询进程,临时关闭非必要查询 |
锁竞争/自旋 | us+sy高,线程栈显示锁等待(如synchronized/ReentrantLock) | 分析锁粒度,是否存在全局锁、锁持有时间过长 | 临时减少线程数,降低锁竞争概率 |
2. 内核态高(sy≥30%):系统/内核层问题
场景 | 指标特征 | 排查要点 | 临时解决 |
系统调用频繁 | strace显示read/write/recv调用过万次,sy高 | 检查代码是否频繁小IO、短连接,是否缺乏缓冲 | 优化IO缓冲,用连接池,批量处理IO操作 |
上下文切换频繁 | vmstat显示cs>10万次/秒,sy高,等待进程数(r)高 | 查看线程数(pstree -p PID | wc -l),是否远超CPU核心数 | 调整线程池大小,避免过度创建线程 |
内核线程异常 | kswapd0/kworker进程%CPU高,si/so>0或中断数高 | kswapd0高→内存不足;kworker高→中断处理异常 | 释放内存/关闭swap,禁用无用硬件中断 |
虚拟化抢占 | st≥5%,云服务器宿主机负载高 | 查看云厂商监控,确认宿主机资源使用情况 | 向云厂商提工单,临时迁移服务器 |
3. 伪CPU瓶颈:内存/IO/网络问题
这类问题不是CPU性能不足,先解决原瓶颈,CPU卡顿会自动消失:
- 内存瓶颈:si/so>0,kswapd0进程高CPU,CPU消耗在交换分区换页。排查:`free -h`看内存,`ps -eo rss,pid,cmd | sort -k1 -r`找内存大户,释放内存或扩容;
- IO瓶颈:wa≥20%,CPU闲等IO。排查:`iostat -x 1`看磁盘%util,`netstat -s`看网络重传,用SSD替代HDD或优化网络协议;
- 网络瓶颈:网络包丢失/延迟高,应用反复重传。排查:`ping`/`traceroute`测延迟,`tcpdump`抓包分析,联系运营商调整配置。
四、分层优化:从临时止损到架构升级
优化遵循“先应急止损→再根因优化→最后架构升级”,优先选低成本、无侵入方案,再考虑重改造。
1. 临时止损(生产环境紧急处理,5分钟见效)
核心目标:快速降低CPU负载,恢复业务可用,不深究根因,仅做应急操作:
- 重启异常进程:无状态进程(Java/PHP应用)直接`kill -9 PID`重启,有状态进程(数据库)先备份数据再处理;
- 调整进程优先级:`renice -n 19 1234`降低高CPU进程优先级,避免抢占核心业务资源;
- 限制CPU配额:用cgroup限制进程CPU使用,如限制为1核:`cgcreate -g cpu:/cpulimit`+`echo 1024 > /sys/fs/cgroup/cpu/cpulimit/cpu.cfs_quota_us`;
- 关闭非必要任务:暂停非核心定时任务、后台进程、测试服务,释放CPU资源;
- 临时扩容:云服务器快速升级CPU(4核→8核),或启动备用节点分担负载。
2. 系统/业务层优化(根因解决,长期有效)
(1)业务代码优化(核心,80%问题源于此)
- 修复代码BUG:消除死循环、无限递归,通过单元测试/压测提前发现问题;
- 优化算法与数据结构:把O(n²)嵌套循环改为O(nlogn),减少计算量;
- 减少重复计算:用本地缓存(Caffeine)、分布式缓存(Redis)缓存高频结果;
- 优化多线程与锁:减小锁粒度(分段锁),用无锁编程(CAS)、读写锁替代全局锁,避免锁竞争;
- 避免频繁对象创建:用对象池/连接池复用资源,减少GC压力(Java/Python等带GC语言)。
(2)应用与系统配置优化
- 应用优化:数据库优化(加索引、分库分表、优化慢查询),异步处理耗时操作(MQ队列),合理设置连接池核心数;
- 系统调优:修改`/etc/sysctl.conf`优化内核参数(如`vm.swappiness=0`关闭swap、`kernel.sched_autogroup_enabled=1`优化调度),执行`sysctl -p`生效;用`taskset -c 0-3 1234`绑定CPU亲和性,避免跨核心调度;
- 日志优化:降低日志级别(DEBUG→INFO),日志落盘改为缓冲刷盘,减少频繁文件IO。
3. 架构层优化(终极方案,避免复发)
适合高并发、高负载场景,从架构上分散CPU压力,突破单服务器性能上限:
- 水平扩容:增加服务器节点,通过负载均衡(Nginx/LVS/K8s Service)分发请求;
- 垂直拆分:将CPU密集型与IO密集型服务分开部署,避免相互抢占资源;
- 微服务化:单体应用拆分为多个微服务,独立部署、扩容,避免单个服务瓶颈影响整体;
- 离线计算:报表统计、数据同步等非实时任务,放到离线集群(Spark/Flink)处理;
- 异构计算:AI、大数据等CPU密集型任务,卸载到GPU/TPU,释放CPU资源。
五、自动化工具:Linux CPU性能排查脚本
基于bash编写,无额外依赖,覆盖瓶颈初判、伪瓶颈检测、高耗进程/线程定位、日志留存,可直接在生产环境运行,一键生成排查报告。
1. 脚本核心功能
- 自动采集CPU基础信息(核心数、型号),对比核心数判断负载是否过高;
- 检测内存/IO伪瓶颈,给出优先排查建议,避免方向偏差;
- 列出TOP10高CPU进程、指定进程TOP5高耗线程,自动转换TID为十六进制;
- 红标高亮异常指标,生成时间戳命名日志,方便归档;
- 输出简洁总结和操作建议,非专业人员也能看懂。
2. 完整脚本代码
#!/bin/bash
# Linux CPU性能自动化排查脚本
# 适用:CentOS/Ubuntu/云服务器等主流Linux,无额外依赖
# 日志保存:/var/log/cpu_check/ (自动创建)
set -e
# ====================== 【配置区:可自定义阈值】======================
CPU_IDLE_LOW=20 # CPU空闲率低阈值,<此值告警(默认20%)
IO_WA_HIGH=20 # IO等待高阈值,≥此值提示伪瓶颈(默认20%)
SWAP_USAGE_HIGH=0 # 交换分区读写阈值,>此值提示内存瓶颈(默认0)
ST_HIGH=5 # 虚拟化抢占阈值(云服务器,默认5%)
TOP_PROC_NUM=10 # 显示TOP高CPU进程数(默认10)
TOP_THREAD_NUM=5 # 单个进程显示TOP高CPU线程数(默认5)
CHECK_THREAD_PID="" # 目标进程PID,空则取CPU最高进程
LOG_DIR="/var/log/cpu_check" # 日志保存目录
# ==============================================================================
# 颜色定义(终端高亮)
RED='\033[31m' # 严重异常
YELLOW='\033[33m'# 警告/伪瓶颈
GREEN='\033[32m' # 正常
NC='\033[0m' # 重置颜色
# 初始化日志目录
init_log() {
if [ ! -d $LOG_DIR ]; then
mkdir -p $LOG_DIR
chmod 755 $LOG_DIR
fi
# 日志命名:cpu_check_年-月-日_时-分-秒.log
LOG_FILE="${LOG_DIR}/cpu_check_$(date +%Y-%m-%d_%H-%M-%S).log"
touch $LOG_FILE
chmod 644 $LOG_FILE
}
# 打印标题(同时写入日志)
print_title() {
local title="$1"
echo -e "\n==================================== $title ====================================" | tee -a $LOG_FILE
echo -e "检测时间:$(date +%Y-%m-%d\ %H:%M:%S)" | tee -a $LOG_FILE
}
# 打印普通信息(同时写入日志)
print_info() {
local info="$1"
echo -e "$info" | tee -a $LOG_FILE
}
# 打印告警信息(高亮,同时写入日志)
print_alert() {
local color="$1"
local alert="$2"
echo -e "${color}${alert}${NC}" | tee -a $LOG_FILE
}
# 1. 采集CPU基础信息
check_cpu_base() {
print_title "CPU基础信息"
CPU_MODEL=$(grep 'model name' /proc/cpuinfo | head -1 | awk -F: '{gsub(/^ /,"",$2);print $2}')
CPU_CORES=$(lscpu | grep '^CPU(s):' | head -1 | awk '{print $2}')
CPU_ARCH=$(lscpu | grep '^Architecture:' | awk '{print $2}')
UPTIME=$(uptime | awk -F, '{gsub(/^ /,"",$1);print $1}')
print_info "CPU型号:$CPU_MODEL"
print_info "逻辑核心数:$CPU_CORES 核"
print_info "CPU架构:$CPU_ARCH"
print_info "服务器运行时间:$UPTIME"
}
# 2. 检测系统负载 & CPU利用率
check_cpu_core() {
print_title "CPU核心指标(负载+利用率)"
# 提取系统负载(1/5/15分钟)
LOAD_1=$(uptime | awk -F'load average: ' '{print $2}' | cut -d, -f1 | sed 's/ //g')
LOAD_5=$(uptime | awk -F'load average: ' '{print $2}' | cut -d, -f2 | sed 's/ //g')
LOAD_15=$(uptime | awk -F'load average: ' '{print $2}' | cut -d, -f3 | sed 's/ //g')
# 提取CPU利用率各子项
CPU_US=$(top -bn1 | grep '%Cpu(s):' | awk '{print $2}' | sed 's/us,//g')
CPU_SY=$(top -bn1 | grep '%Cpu(s):' | awk '{print $4}' | sed 's/sy,//g')
CPU_ID=$(top -bn1 | grep '%Cpu(s):' | awk '{print $8}' | sed 's/id,//g')
CPU_WA=$(top -bn1 | grep '%Cpu(s):' | awk '{print $10}' | sed 's/wa,//g')
CPU_SI=$(top -bn1 | grep '%Cpu(s):' | awk '{print $14}' | sed 's/si,//g')
CPU_ST=$(top -bn1 | grep '%Cpu(s):' | awk '{print $16}' | sed 's/st,//g')
# 打印原始指标
print_info "系统负载(1/5/15分钟):$LOAD_1 / $LOAD_5 / $LOAD_15"
print_info "CPU利用率:us($CPU_US%) | sy($CPU_SY%) | id($CPU_ID%) | wa($CPU_WA%) | si($CPU_SI%) | st($CPU_ST%)"
print_info "负载判断基准:当前${CPU_CORES}核,负载>${CPU_CORES}即为过高"
# 负载异常判断
if (( $(echo "$LOAD_15 > $CPU_CORES" | bc -l) )); then
print_alert $RED "【严重异常】15分钟负载$LOAD_15 > 核心数$CPU_CORES,进程阻塞等CPU!"
elif (( $(echo "$LOAD_5 > $CPU_CORES" | bc -l) )); then
print_alert $YELLOW "【警告】5分钟负载$LOAD_5 > 核心数$CPU_CORES,负载上升中!"
else
print_alert $GREEN "【正常】系统负载合理,无CPU调度阻塞"
fi
# 空闲率异常判断
if (( $(echo "$CPU_ID< $CPU_IDLE_LOW" | bc -l) )); then
print_alert $RED "【严重异常】CPU空闲率$CPU_ID% < $CPU_IDLE_LOW%,资源耗尽!"
else
print_alert $GREEN "【正常】CPU空闲率充足,无纯CPU瓶颈"
fi
# 内核态过高/虚拟化抢占判断
if (( $(echo "$CPU_SY >= 30" | bc -l) )); then
print_alert $YELLOW "【警告】内核态占比$CPU_SY% ≥30%,可能系统调用异常!"
fi
if (( $(echo "$CPU_ST >= $ST_HIGH" | bc -l) )); then
print_alert $YELLOW "【警告】虚拟化抢占st$CPU_ST% ≥$ST_HIGH%,云服务器被抢占资源!"
fi
# 保存指标供后续伪瓶颈判断
export CPU_ID CPU_WA CPU_SI
}
# 3. 检测伪CPU瓶颈(内存/IO)
check_fake_bottleneck() {
print_title "伪CPU瓶颈检测(内存/IO)"
# 内存伪瓶颈
if (( $(echo "$CPU_SI > $SWAP_USAGE_HIGH" | bc -l) )); then
print_alert $RED "【伪瓶颈-内存】交换分区读si$CPU_SI% 超标,内存不足导致CPU换页消耗!"
print_info "优先操作:free -h 查内存,释放内存/关swap,内存问题解决后CPU会恢复"
else
print_alert $GREEN "【正常】无内存导致的伪CPU瓶颈"
fi
# IO伪瓶颈
if (( $(echo "$CPU_WA >= $IO_WA_HIGH" | bc -l) )); then
print_alert $RED "【伪瓶颈-IO】IO等待wa$CPU_WA% 超标,CPU等IO,非CPU本身问题!"
print_info "优先操作:iostat -x 1 查磁盘IO,netstat -s 查网络,解决IO瓶颈"
else
print_alert $GREEN "【正常】IO等待率合理,无IO导致的伪CPU瓶颈"
fi
}
# 4. 定位TOP高CPU进程
check_top_proc() {
print_title "TOP${TOP_PROC_NUM}高CPU进程(PID/CPU%/用户/命令)"
TOP_PROC=$(ps -eo pid,ppid,pcpu,user,cmd --no-headers | grep -v "cpu_perf_check.sh" | sort -k3 -r | head -$TOP_PROC_NUM)
if [ -z "$TOP_PROC" ]; then
print_info "未检测到高CPU进程(已排除本脚本)"
else
printf "%-8s %-8s %-8s %-10s %s\n" "PID" "PPID" "CPU%" "USER" "COMMAND" | tee -a $LOG_FILE
echo "$TOP_PROC" | while read -r line; do
PID=$(echo $line | awk '{print $1}')
PPID=$(echo $line | awk '{print $2}')
PCPU=$(echo $line | awk '{print $3}')
USER=$(echo $line | awk '{print $4}')
CMD=$(echo $line | cut -d' ' -f5-)
printf "%-8s %-8s %-8s %-10s %s\n" "$PID" "$PPID" "$PCPU%" "$USER" "$CMD" | tee -a $LOG_FILE
done
fi
# 自动获取最高CPU进程PID(未指定时)
if [ -z "$CHECK_THREAD_PID" ]; then
CHECK_THREAD_PID=$(ps -eo pid,pcpu --no-headers | grep -v "cpu_perf_check.sh" | sort -k2 -r | head -1 | awk '{print $1}')
fi
export CHECK_THREAD_PID
}
# 5. 定位指定进程的TOP高CPU线程
check_top_thread() {
print_title "进程PID[$CHECK_THREAD_PID]的TOP${TOP_THREAD_NUM}高CPU线程"
# 检查PID是否存在
if ! ps -p $CHECK_THREAD_PID > /dev/null 2>&1; then
print_alert $YELLOW "【警告】进程PID[$CHECK_THREAD_PID]不存在,跳过线程排查"
return
fi
TOP_THREAD=$(pidstat -u -t -p $CHECK_THREAD_PID 1 1 | grep -v "Average" | grep -v "pidstat" | sort -k4 -r | head -$TOP_THREAD_NUM)
if [ -z "$TOP_THREAD" ]; then
print_info "未检测到该进程的高CPU线程"
else
printf "%-14s %-14s %-8s %s\n" "TID(十进制)" "TID(十六进制)" "CPU%" "COMMAND" | tee -a $LOG_FILE
echo "$TOP_THREAD" | while read -r line; do
TID_DEC=$(echo $line | awk '{print $2}')
TID_HEX=$(printf "%x" $TID_DEC) # 转十六进制(供pstack使用)
TCPU=$(echo $line | awk '{print $4}')
TCMD=$(echo $line | cut -d' ' -f5-)
printf "%-14s %-14s %-8s %s\n" "$TID_DEC" "$TID_HEX" "$TCPU%" "$TCMD" | tee -a $LOG_FILE
done
print_info "线程排查命令:printf %x\\n $TID_DEC → pstack $CHECK_THREAD_PID | grep -A 10 十六进制TID"
fi
}
# 6. 生成排查总结
check_summary() {
print_title "本次CPU排查总结"
print_info "1. 排查日志已保存至:${GREEN}$LOG_FILE${NC}"
print_info "2. 严重异常处理:重启/降优先级高CPU进程(kill -9 PID | renice -n 19 PID)"
print_info "3. 伪瓶颈处理:先解决内存/IO问题,再复查CPU"
print_info "4. 内核态/线程异常:strace -c -p PID 查系统调用,pstack PID 查线程栈"
print_info "5. 多核不均排查:mpstat -P ALL 1 5 查单个核心利用率"
}
# 主执行流程
main() {
clear
echo -e "${GREEN}========== Linux CPU性能自动化排查脚本 ==========${NC}"
init_log
check_cpu_base
check_cpu_core
check_fake_bottleneck
check_top_proc
check_top_thread
check_summary
echo -e "\n${GREEN}排查完成!日志已留存,建议备份用于后续根因分析${NC}"
}
# 执行主函数
main 3. 脚本使用与扩展
(1)基础使用步骤
# 保存脚本并赋予执行权限
touch /usr/local/bin/cpu_perf_check.sh
chmod +x /usr/local/bin/cpu_perf_check.sh
# 直接运行(终端输出+日志留存)
cpu_perf_check.sh
# 后台运行(仅生成日志,适合卡顿严重时)
nohup cpu_perf_check.sh > /dev/null 2>&1 & (2)自定义配置
编辑脚本“配置区”,按业务调整阈值:
- 高负载业务可将`CPU_IDLE_LOW`设为10%,IO密集型业务将`IO_WA_HIGH`设为30%;
- 指定`CHECK_THREAD_PID=1234`,可直接排查目标进程(如MySQL)的线程;
- 修改`LOG_DIR`,将日志保存到指定目录。
(3)生产环境扩展建议
- 定时监控:加入crontab,每10分钟执行一次(`*/10 * * * * /usr/local/bin/cpu_perf_check.sh > /dev/null 2>&1`);
- 自动告警:在`print_alert`函数中添加企业微信/钉钉机器人,异常时推送告警;
- 容器适配:结合`docker exec`/`kubectl exec`,实现容器级CPU排查;
- 监控联动:将指标写入Prometheus,用Grafana做可视化仪表盘,跟踪性能趋势。
六、监控与复盘:形成闭环防复发
排查优化后,建立常态化监控与复盘机制,避免CPU卡顿反复。
1. 核心监控指标与工具
长期监控以下指标,设置基线(如正常CPU利用率<60%、cs<5万次/秒),偏离基线及时告警:
- 宏观指标:CPU利用率(us/sy/id/wa)、1/5/15分钟负载、上下文切换数(cs)、中断数(in);
- 微观指标:TOP N高CPU进程/线程、核心利用率分布、JVM GC指标(Java应用);
- 业务指标:接口响应时间(RT)、QPS、并发数(联动CPU指标,分析业务压力与CPU的关联)。
工具推荐:开源方案(Prometheus+Grafana+Node Exporter)、商业方案(阿里云ARMS、腾讯云CM),可实现指标实时采集、可视化展示与告警推送,适配物理机、云服务器及容器环境。
2. 常态化监控落地方案
监控不是单纯采集指标,核心是“基线建立→告警触发→快速响应”,形成自动化闭环,具体落地步骤如下:
- 建立指标基线:基于业务低峰/高峰时段数据,确定各指标正常范围(如高峰CPU利用率≤70%、上下文切换cs≤5万次/秒、IO等待wa≤10%),避免误告警;
- 分层告警配置:按严重程度设置告警级别,一级告警(CPU空闲率<10%、st≥8%)触发电话/企业微信紧急推送,二级告警(负载持续升高、sy≥30%)触发短信通知,三级告警(指标偏离基线但不影响业务)仅记录日志;
- 告警联动排查:将告警与前文自动化脚本关联,告警触发时自动执行脚本,生成排查报告,同步至运维工单系统,减少人工介入时间;
- 趋势跟踪分析:通过Grafana绘制CPU指标周/月趋势图,提前识别性能衰减(如每周同一时段CPU利用率上升5%),主动优化而非被动响应。
3. 复盘机制:避免问题复发
每一次CPU卡顿问题解决后,需进行系统性复盘,形成文档沉淀,避免同类问题重复出现,复盘核心要点包括:
- 根因归档:记录问题现象、指标特征、根因(如死循环代码、内核参数不合理、云服务器宿主机抢占)、解决方案及验证结果,按场景分类存储(用户态/内核态/伪瓶颈);
- 优化沉淀:将有效解决方案转化为标准化操作(SOP),如内核参数优化配置、线程池合理大小计算公式、缓存策略规范等,嵌入开发/运维流程;
- 预案演练:定期开展性能故障演练,模拟CPU满负载、内核态高、内存伪瓶颈等场景,验证监控告警有效性、排查脚本准确性及团队响应速度,优化应急流程;
- 技术迭代:针对反复出现的同类问题,推动架构/代码层面迭代(如将频繁引发锁竞争的模块微服务化、用GPU替代CPU处理计算密集型任务),从根源规避风险。
4. 核心总结
CPU性能问题的治理核心是“精准排查+分层优化+闭环监控”:排查时先区分纯CPU瓶颈与伪瓶颈,避免方向偏差;优化时优先应急止损,再逐步推进根因优化与架构升级;长期保障需依赖常态化监控与复盘,将被动解决问题转化为主动预防风险。结合本文工具、脚本与方案,可覆盖Linux服务器CPU性能全生命周期管理,提升系统稳定性与运维效率。
版权所属:SO JSON在线解析
原文地址:https://www.sojson.com/blog/573.html
转载时必须以链接形式注明原始出处及本声明。
如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。
