帮助中心 > 关于独立服务器 > Linux服务器CPU 100%的问题诊断与自动化处理脚本分享
Linux服务器CPU 100%的问题诊断与自动化处理脚本分享
时间 : 2025-09-11 14:47:04
编辑 : Jtti

Linux运维中CPU使用率到达100%属于常见但是严重影响系统性能的问题,这种情况会导致服务响应缓慢,甚至完全无响应直接关系到业务运行。Linux服务器使用中药如何实现自动化诊断和处理CPU占用过高问题?

当服务器CPU使用率持续维持在100%时,首先需要识别是用户空间进程还是系统内核占用了大量CPU资源。常见原因包括异常进程、死循环、资源竞争、配置不当或应用程序bug。手动诊断通常需要执行一系列命令:使用tophtop查看整体CPU使用情况,识别高CPU占用的进程;通过ps命令进一步分析进程详细信息;使用strace跟踪进程的系统调用;或者通过perf进行性能剖析。然而,在紧急情况下,手动执行这些步骤既耗时又容易出错。

为此,我们开发了一个自动化诊断脚本,能够系统性地收集关键信息并采取适当措施。以下是完整的脚本代码:

#!/bin/bash
# 定义输出颜色
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志文件设置
LOG_DIR="/tmp/cpu_analysis"
mkdir -p $LOG_DIR
LOG_FILE="$LOG_DIR/cpu_analysis_$(date +%Y%m%d_%H%M%S).log"
# 记录日志函数
log() {
echo -e "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}
# 检查命令是否存在
check_command() {
if ! command -v $1 &> /dev/null; then
log "${RED}错误: $1 命令未找到,请安装后再运行脚本${NC}"
exit 1
fi
}
# 系统概览
system_overview() {
log "${GREEN}收集系统概览信息...${NC}"
echo "CPU使用率TOP 10进程:" >> $LOG_FILE
ps aux --sort=-%cpu | head -11 >> $LOG_FILE
echo "" >> $LOG_FILE
echo "内存使用情况:" >> $LOG_FILE
free -h >> $LOG_FILE
echo "" >> $LOG_FILE
echo "系统运行时间和平均负载:" >> $LOG_FILE
uptime >> $LOG_FILE
echo "" >> $LOG_FILE
}
# 识别高CPU占用进程
identify_high_cpu_processes() {
log "${GREEN}识别高CPU占用进程...${NC}"
local threshold=50
local high_cpu_processes=$(ps aux --sort=-%cpu | awk -v threshold="$threshold" 'NR>1 && $3 > threshold {print $2, $3, $11}')
if [ -z "$high_cpu_processes" ]; then
log "${YELLY}未发现CPU占用超过${threshold}%的进程${NC}"
return 1
else
echo "高CPU占用进程(PID, CPU%, 命令):" >> $LOG_FILE
echo "$high_cpu_processes" >> $LOG_FILE
echo "" >> $LOG_FILE
return 0
fi
}
# 详细进程分析
analyze_process() {
local pid=$1
log "${GREEN}分析进程 $pid ...${NC}"
echo "进程详细信息:" >> $LOG_FILE
ps -p $pid -o pid,ppid,user,%cpu,%mem,vsz,rss,tty,stat,start,time,command >> $LOG_FILE
echo "" >> $LOG_FILE
echo "进程命令行参数:" >> $LOG_FILE
cat /proc/$pid/cmdline 2>/dev/null | xargs -0 echo >> $LOG_FILE
echo "" >> $LOG_FILE
echo "进程打开的文件:" >> $LOG_FILE
lsof -p $pid 2>/dev/null | head -20 >> $LOG_FILE
echo "" >> $LOG_FILE
}
# 收集系统状态信息
collect_system_stats() {
log "${GREEN}收集系统状态信息...${NC}"
echo "CPU核心数:" >> $LOG_FILE
nproc >> $LOG_FILE
echo "" >> $FILE
echo "每个CPU核心的使用情况:" >> $LOG_FILE
mpstat -P ALL 1 1 >> $LOG_FILE
echo "" >> $LOG_FILE
echo "内核调用统计:" >> $LOG_FILE
sar -n DEV 1 1 >> $LOG_FILE
echo "" >> $LOG_FILE
echo "磁盘I/O统计:" >> $LOG_FILE
iostat -x 1 1 >> $LOG_FILE
echo "" >> $LOG_FILE
echo "内存统计:" >> $LOG_FILE
vmstat 1 2 >> $LOG_FILE
echo "" >> $LOG_FILE
}
# 收集Java进程信息(如果适用)
analyze_java_process() {
local pid=$1
if ps -p $pid -o comm= | grep -q java; then
log "${GREEN}检测到Java进程,收集JVM信息...${NC}"
# 检查jstack是否可用
if command -v jstack &> /dev/null; then
echo "Java线程栈跟踪:" >> $LOG_FILE
jstack $pid >> $LOG_FILE 2>&1
echo "" >> $LOG_FILE
else
echo "jstack不可用,无法收集Java线程信息" >> $LOG_FILE
fi
fi
}
# 生成分析报告
generate_report() {
log "${GREEN}生成分析报告...${NC}"
echo "CPU 100%问题分析报告" >> $LOG_FILE
echo "生成时间: $(date)" >> $LOG_FILE
echo "==========================================" >> $LOG_FILE
}
# 安全结束异常进程(需要谨慎使用)
safe_kill_process() {
local pid=$1
local process_name=$(ps -p $pid -o comm= 2>/dev/null)
if [ -z "$process_name" ]; then
log "${RED}进程 $pid 不存在${NC}"
return
fi
log "${YELLOW}尝试安全结束进程 $pid ($process_name)...${NC}"
# 首先尝试正常终止
kill $pid 2>/dev/null
sleep 2
# 检查进程是否仍在运行
if ps -p $pid > /dev/null; then
log "${YELLOW}正常终止失败,尝试强制终止...${NC}"
kill -9 $pid 2>/dev/null
if [ $? -eq 0 ]; then
log "${GREEN}已强制终止进程 $pid${NC}"
else
log "${RED}无法终止进程 $pid${NC}"
fi
else
log "${GREEN}已正常终止进程 $pid${NC}"
fi
}
# 主函数
main() {
log "${GREEN}开始CPU 100%问题诊断...${NC}"
# 检查必要命令
check_command "ps"
check_command "top"
check_command "mpstat"
check_command "iostat"
check_command "vmstat"
check_command "lsof"
# 生成报告
generate_report
# 收集系统信息
system_overview
collect_system_stats
# 识别高CPU进程
if identify_high_cpu_processes; then
echo "$high_cpu_processes" | while read line; do
pid=$(echo $line | awk '{print $1}')
cpu_usage=$(echo $line | awk '{print $2}')
command=$(echo $line | awk '{print $3}')
log "${RED}发现高CPU占用进程: PID=$pid, CPU使用率=$cpu_usage%, 命令=$command${NC}"
# 分析进程
analyze_process $pid
# 如果是Java进程,额外收集信息
analyze_java_process $pid
# 询问是否终止进程
read -p "是否终止此进程? (y/N): " answer
case $answer in
[Yy]*)
safe_kill_process $pid
;;
*)
log "${YELLOW}跳过终止进程 $pid${NC}"
;;
esac
done
fi
log "${GREEN}诊断完成。详细日志请查看: $LOG_FILE${NC}"
log "${GREEN}建议根据日志分析结果进一步调整系统配置或应用程序${NC}"
}
# 执行主函数
main "$@"

这个脚本的设计思路是逐步深入诊断CPU问题。首先收集系统整体状态信息,包括CPU、内存和负载情况,提供问题发生的上下文环境。然后识别占用CPU资源最高的进程,获取这些进程的详细信息,包括启动参数、打开的文件和资源使用情况。

对于Java应用程序,脚本特别增加了JVM信息收集功能,通过jstack命令获取线程堆栈跟踪,这对于诊断Java应用中的死循环或线程阻塞问题特别有用。脚本还提供了交互式进程终止功能,但需要管理员确认后才执行,避免误杀重要进程。

脚本执行完成后,会在/tmp/cpu_analysis目录下生成详细的日志文件,包含所有收集到的系统信息和进程数据。管理员可以分析这些信息,找出CPU占用过高的根本原因,如特定应用程序的bug、配置不当、资源竞争或硬件不足等问题。

需注意脚本只是一个诊断工具,它可以帮助快速定位问题,但解决问题的根本方法通常需要根据诊断结果进一步优化应用程序、调整系统参数或增加硬件资源。定期运行系统健康检查、实施监控告警机制以及建立性能基线,都是预防CPU 100%问题的有效手段。

相关内容

讨论视频直播和点播对香港服务器带宽的需求有区别吗? 日本服务器IP异常排查和解封是实用技巧 服务器BGP多线路冗余到底有什么优势 香港服务器和日本/新加坡节点在延迟优化上的差异化优势分析 MySQL异步复制与TiDB多副本同步在跨地域环境下的差异分析 跨地域服务器集群数据同步的加速方案有哪些 香港大带宽服务器能降低ping值吗? 视频下载服务器更看重带宽还是硬盘? 租用香港大硬盘服务器做数据存储怎么样 什么情况下服务器需要用到GPU显卡
返回

24/7/365 全天候支持我们时刻恭候您

帮助中心