Linux服务器卡顿之CPU性能全流程分析与落地实践

JSON 2026-01-28 15:54:51 345

一、核心认知: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消耗多是单个线程导致,需从进程中定位具体线程,步骤如下:

  1. 获取高CPU线程TID:`top -H -p 1234`(按P排序)或`ps -mp 1234 -o THREAD,tid,pcpu | sort -k3 -r`;
  2. TID转十六进制:`printf "%x\n" 5678`(jstack/pstack日志用十六进制标识线程);
  3. 查看线程调用栈:`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

转载时必须以链接形式注明原始出处及本声明。

本文主题:

如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。

关于作者
一个低调而闷骚的男人。
相关文章
SOJSON 拓展服务器被DDos攻击了一晚上,是如何解决的?
SQL外连接剖
Java获取浏览请求头(User-Agent),分析浏览信息,系统信息的几种办法。
SQL外连接剖
TCP 和 UDP协议详细讲解,优缺点分析讲解
阿里云双11活动购买详细说明,阿里云最低86元起一年服务器购买详情
Redis 单线程模型分析
cpu资源采集.json
Flink 在又拍云日志批处理中的实践
Linux—文件树
最新文章
文件上传漏洞与防御 4058
前端构建工具选型指南:Webpack、Vite、Rollup、esbuild 深度对比 1444
物联网时代2026年时序数据库选型指南 1151
SaaS行业面临AI挑战:从“无限复用”到“灵活适应” 1269
神经网络:从构造到模型训练全链路解析 1168
一文吃透 Redis 核心存储结构:ziplist、listpack 与哈希表扩容 / 并发查询 1593
Linux sudo提权完整指南:从基础用法到生产级安全配置 691
XSS 和 CSRF 的本质区别及开发防御全解析 772
JVM垃圾回收(GC)全维度解析:从原理到调优实战 813
Linux动静态库与ELF加载全解析:从实操制作到底层原理 912
最热文章
免费天气API,天气JSON API,不限次数获取十五天的天气预报 783114
最新MyEclipse8.5注册码,有效期到2020年 (已经更新) 711464
苹果电脑Mac怎么恢复出厂系统?苹果系统怎么重装系统? 679993
Jackson 时间格式化,时间注解 @JsonFormat 用法、时差问题说明 562673
我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比 512621
Elasticsearch教程(四) elasticsearch head 插件安装和使用 484794
Jackson 美化输出JSON,优雅的输出JSON数据,格式化输出JSON数据... ... 302947
Java 信任所有SSL证书,HTTPS请求抛错,忽略证书请求完美解决 247433
Elasticsearch教程(一),全程直播(小白级别) 233097
谈谈斐讯路由器劫持,你用斐讯路由器,你需要知道的事情 228329
支付扫码

所有赞助/开支都讲公开明细,用于网站维护:赞助名单查看

查看我的收藏

正在加载... ...