暑假运维学习打卡第二十九天8.29

场景二:服务器变"牛车"------CPU负载飙升

模拟情景:用户反馈系统响应极慢,top 看到 load average 高达 15.0。你需要找出是哪个进程在疯狂消耗CPU,并分析它是否正常。

准备工作

第一步:创建一个CPU 跑满 且会反复自杀重启的坏脚本

进入你的家目录

cd ~

创建脚本,内容是一个死循环,疯狂进行数学运算消耗CPU

cat > bad.sh << 'EOF'

#!/bin/bash

while true

do

echo "I am a bad process, eating CPU..."

纯计算,不写磁盘,避免IO干扰

echo "scale=1000; 4*a(1)" | bc -l 2>/dev/null &

done

EOF

赋予执行权限

chmod +x bad.sh

第二步:配置 Systemd 服务(模拟"自动复活"机制)

sudo tee /etc/systemd/system/bad.service > /dev/null << 'EOF'

Unit

Description=Evil CPU Eater

After=network.target

Service

Type=simple

ExecStart=/bin/bash /root/bad.sh # 注意:如果你不是root用户,请改成 /home/你的用户名/bad.sh

Restart=always

RestartSec=3

Install

WantedBy=multi-user.target

EOF

重载 systemd 并启动这个"恶魔"

sudo systemctl daemon-reload

sudo systemctl start bad

sudo systemctl enable bad # 设置开机自启,增加难度

第三步:再放几个"烟雾弹"进程(模拟正常业务)

用 stress 再压榨两核(如果没有 yum install -y stress 先装一下)

stress --cpu 1 --timeout 600 &

再开一个消耗CPU的 dd 进程

dd if=/dev/zero of=/dev/null &

开始实操

步骤一:实时刷新系统进程列表,按 CPU 占用率从高到低排序显示。

使用top命令,进入交互界面,再按大写C键,使这些进程按照CPU占用率排列。同时再按小写c键,可以让最后一列的COMMAND列显示命令的完整路径。

这个是按下C以及c键后的结果:

这个是仅按下C键后的效果:

目的:找到了占用CPU的进程,获得了他们的PID。

步骤二:拿到了 PID(比如 12345),需要查出这个进程是在哪个目录 启动的,以及它启动时带了什么环境变量。(不会)

Linux 内核会把每个运行中的进程信息,放在 /proc 目录下一个以 数字(PID) 命名的文件夹里。

其中cwd指的是进程的的工作目录;environ保存了其所有环境变量;exe则是其执行程序的绝对路径。

所以:想找到一个进程的启动目录,可以使用

readlink /proc/进程PID/cwd

即可找到该进程的启动目录

接着查看该程序环境变量:

cat /proc/4416/environ | tr '\0' '\n'

这里使用管道符连接 tr 命令,将原本environ文件中不同变量之间的空字符替换成换行符,输出时各个环境变量都能独占一行,更加清晰明了。

步骤三:尝试删除坏进程

在我们启动bad.sh后,出现了很多bc -l 的进程,以及bad.sh本身的进程。尝试使用:

sudo kill -9 PID

的方法删除bc -l 进程,结果发现删除后不一会就又都重新出现了;即使用同样的命令删除bad.sh进程本身,也还是同样的结果:bc进程重新出现,bad.sh本身也换了一个PID 重新在运行。

询问AI后得知,在我们的准备工作中,已将bad.sh注册成了Systemd服务 bad.service,而那些bc -l实际上就是它的子进程。我们在最开始的服务配置中,有一行设置:Restart=always。这代表,当我们用kill杀死这个进程时,Systemd就会马上重启这个进程,导致我们无法删除。

步骤四:不只要杀死进程,还要让它永远不再自动重启。

理解了是Systemd在保护 bad.sh进程,我们就要使用systemctl命令来处理它。使用:

sudo systemctl stop bad

在使用这个命令后,可以发现top中的原本大量存在的bc进程以及bad.sh本身都不见了。

同时我们还要解决其原本设置的开机自启,以防以后对cpu进行恶意占用

sudo systemctl disable bad

小插曲

在刚开始启动bad.sh时,用top命令查看进程,却发现进程中有很多的bc -l 进程,而bad.sh本身其实占的CPU并不多,大概是这样:

而且他们还会动态变化,有些时候甚至看不到bad.sh进程本身。询问AI后得知,这些bc -l是bad的子进程,bad作为父进程,启动了这些子进程,而真正消耗,占据大量CPU的其实是子进程本身。如果遇到都是子进程的情况,可以使用:

pstree -p -s PID

查看该进程的父子关系,这样就可以找出某个垃圾进程的根源,对其进行修改了。

总结

top和systemd服务的使用

相关推荐
代码山河6 小时前
Python就业方向全解析:后端、爬虫、数据分析、AI你选哪个?
python·学习·架构·教程·面向对象·项目
释厄6237 小时前
AI学习层更新与跨体转移律——人类社会同构·不缺理解缺 U
人工智能·学习
小嘉丶学长11 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
小李不想当小白11 小时前
SPI通信外设与W25Q64 (硬件SPI)(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
adinnet202615 小时前
电商客服对话知识库的自学习闭环与质量演进机制
学习
lazy H15 小时前
【计算机网络】第 13 篇:NAT 和端口映射是什么?为什么本地服务外网访问不了?
java·网络·网络协议·学习·计算机网络·408
试剂界的爱马仕16 小时前
α-Cyano-4-hydroxycinnamic acid(CHCA)用作 MALDI-TOF 基质的配制与使用
大数据·人工智能·深度学习·学习
小向是个Der17 小时前
嵌入式进阶——编译与链接
汇编·单片机·学习·编译原理·交叉编译
学网安的肆伍17 小时前
认证机制攻防学习|PortSwigger Authentication 靶场复现总结(二):用户名枚举进阶
学习·web安全·网络安全·burpsuite·portswigger·认证安全·靶场复现
海绵宝宝转agent18 小时前
Leetcode二叉树算法个人理解
笔记·学习·算法·leetcode·深度优先