《零基础SRE实战(六):系统"听诊器"——Linux进程管理与资源监控全揭秘》

一、引言

大家好,我是正在零基础学习 SRE 云计算运维的学员。上周我们给服务器加上了"密码锁"(用户与权限),这周我们要给服务器做一次"全身查体"。

在 Windows 里,电脑卡了我们会按 Ctrl+Alt+Delete 呼出任务管理器来结束进程。那么在没有图形界面的 Linux 服务器里,我们该如何查看 CPU 占用?怎么知道磁盘有没有满?遇到卡死的程序怎么强制关闭?

今天这篇笔记,就带你掌握 Linux 运维的"听诊器"与"手术刀"!


二、本次环境要求

⚠️ 写在前面: 本次实验涉及系统进程查看与终止,请确保你拥有 sudo 权限或 root 密码。

项目 要求
操作系统 Ubuntu 22.04 / 24.04 Server 版
终端工具 MobaXterm
测试准备 建议多开几个 MobaXterm 终端窗口,方便一边运行命令,一边监控变化

三、实操步骤

第一步:系统资源"大体检"(磁盘与内存)

1.1 查看磁盘使用情况:df -h

磁盘是服务器最金贵的资源之一。一旦磁盘写满,很多服务都会罢工。所以运维人员每天必做的第一件事就是——查磁盘!

zhangsan@sre-server:~$ df -h

📺 模拟的系统输出结果:

文件系统        容量  已用  可用 已用% 挂载点
tmpfs           16G     0   16G    0% /dev/shm
/dev/sda3      200G   45G  145G   24% /
/dev/sda1      976M  260M  716M   27% /boot

🔍 字段解释:

字段 含义 本例中的值
文件系统 磁盘分区的设备名 /dev/sda3/dev/sda1
容量 分区总大小 200G976M
已用 已经使用了多少 45G260M
可用 剩余可用空间 145G716M
已用% 使用百分比 24%27%,超过 90% 就要警惕!
挂载点 这个分区对应哪个目录 / 是根目录,/boot 是启动分区

💡 小贴士-h 参数是 “Human-readable” 的缩写,会自动把字节数转换成人类能看懂的 MB/GB 格式。不加 -h 的话,你会看到一串密密麻麻的数字(单位是 1KB blocks),根本看不懂!


1.2 查看内存使用情况:free -m / free -h

内存(RAM)是程序的"办公桌",所有正在运行的软件都需要占用内存空间。

zhangsan@sre-server:~$ free -h

📺 模拟的系统输出结果:

              total        used        free      shared  buff/cache   available
Mem:           31Gi       8.5Gi       12Gi       123Mi        10Gi        22Gi
Swap:         2.0Gi          0B       2.0Gi

🔍 字段解释:

字段 含义 本例中的值
total 物理内存总量 31Gi(约 32GB)
used 正在被使用的内存 8.5Gi
free 完全空闲的内存 12Gi
shared 被多个程序共享的内存 123Mi
buff/cache 被系统用作缓存的内存 10Gi
available 实际可用内存 22Gi(这是关键指标!)
Swap 交换分区(相当于虚拟内存) 2.0Gi

💡 小贴士:重点关注 available 这一列!它考虑了缓存可回收的情况,代表"真正还能给新程序用的内存"。而 free 看起来很少是正常的——Linux 会把空闲内存用来做缓存,这叫"用空间换速度"。


第二步:Linux 的"任务管理器"(top 与 htop)

2.1 原生监控工具:top

top 是 Linux 自带的进程监控工具,相当于 Windows 的任务管理器。

zhangsan@sre-server:~$ top

📺 模拟的系统输出结果:

top - 14:30:25 up 12:35,  2 users,  load average: 0.52, 0.58, 0.59
任务:   123 total,   1 running, 122 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.2 us,  1.1 sy,  0.0 ni, 95.3 id,  0.0 wa,  0.0 hi,  0.4 si,  0.0 st
MiB Mem :  31944.6 total,  12256.0 free,   8734.5 used,  10954.1 buff/cache
MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.  22016.0 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 1234 root      20   0  512344  45632  12345 S  12.5   0.1   2:30.45 redis-server
 5678 mysql     20   0 1234568 345678  56789 S   5.2   1.1  15:23.67 mysqld
 9012 zhangsan  20   0   12345   4567   2345 S   2.1   0.0   0:01.23 bash
    1 root      20   0  123456  23456  12345 S   0.3   0.1   0:05.67 systemd

🔍 顶部信息行解释:

字段 含义 示例值
top - 14:30:25 当前系统时间 下午 2 点 30 分
up 12:35 系统运行时长 已经运行了 12 小时 35 分钟
2 users 登录用户数 有 2 个用户在线
load average: 0.52, 0.58, 0.59 系统负载(1/5/15分钟) 数值越高说明越繁忙

📊 load average 怎么看?

  • 数值 < CPU 核心数:系统很悠闲
  • 数值 ≈ CPU 核心数:刚好跑满
  • 数值 > CPU 核心数:已经过载,需要排查!

🔍 进程列表列解释:

列名 含义 说明
PID 进程号(Process ID) 每个运行的程序都有一个唯一编号,相当于"身份证"
USER 进程所属用户 谁启动的这个程序
%CPU CPU 占用百分比 这个程序吃了多少 CPU 算力
%MEM 内存占用百分比 这个程序吃了多少内存
TIME+ 累计 CPU 时间 这个程序总共跑了多久
COMMAND 命令名 正在运行什么程序

💡 交互技巧:按下 q 键可以退出 top 界面。按下 M 可以按内存排序,按下 P 可以按 CPU 排序( 大写字母)!


2.2 进阶级监控工具:htop

top 虽然功能强大,但界面比较朴素。htop 是它的升级版,带颜色、进度条,还能用鼠标操作!

# 先安装 htop
zhangsan@sre-server:~$ sudo apt install htop

# 然后启动
zhangsan@sre-server:~$ htop

📺 模拟的系统输出结果:

  CPU [||||||||||          ] 15% | 任务数: 123 | 负载: 0.52
  Mem [||||||||||||||\\] 85% | 正常运行: 12:35
  
  PID USER      PRI NI    VIRT    RES    SHR S CPU% MEM%   TIME+ Command
 1234 root      20  0  512M  45M  12M S  12.5  0.1   2:30 redis-server
 5678 mysql     20  0  1.2G 338M  56M S   5.2  1.1  15:23 mysqld
 9012 zhangsan  20  0   12M 4.5M 2.3M S   2.1  0.0   0:01 bash
    1 root      20  0  120M  23M  12M S   0.3  0.1   0:05 systemd
  
  F1 帮助  F2 设置  F3 搜索  F4 过滤  F5 树状  F6 排序  F7  Nice-  F8  Nice+  F9 杀掉  F10 退出

🔍 htop 的优势:

  1. 带颜色:CPU/内存使用率高的地方会标红,一目了然
  2. 进度条可视化:用条形图显示占用情况,比数字更直观
  3. 支持鼠标:可以用鼠标点击排序、选择进程
  4. F9 杀进程:直接选中进程按 F9,不用再敲 kill 命令

💡 企业实战技巧:很多老工程师更偏爱 top,因为它更稳定、占资源更少。但 htop 对新手更友好,推荐先从 htop 入门!


第三步:精准定位"犯罪嫌疑人"(ps 与 grep)

3.1 静态抓取进程:ps aux

ps 可以"拍照"当前所有进程,但它会一次性列出几百行信息,就像把所有员工的花名册都打印出来一样——根本看不过来!

zhangsan@sre-server:~$ ps aux

📺 模拟的系统输出结果(仅展示前 10 行):

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1 123456 23456 ?        Ss   10:00   0:05 /sbin/init
root       123  0.1  0.2  56789  34567 ?        Ss   10:00   0:12 /lib/systemd/systemd-journald
root       456  0.0  0.0  12345   5678 ?        Ss   10:00   0:01 /usr/sbin/sshd -D
root       789  2.5  1.5 234567 456789 ?        Ssl  10:00  15:30 /usr/sbin/mysqld
root      1234  5.2  0.8  98765 123456 ?        Ssl  10:01  25:45 /usr/sbin/nginx
zhangsan  5678  0.1  0.0   9876   1234 pts/0    Ss   14:00   0:00 -bash
zhangsan  9012  0.2  0.0  12345   2345 pts/0    R+   14:05   0:01 ps aux
root     11111  0.0  0.0   8765   1234 ?        Ss   10:00   0:00 /usr/sbin/crond

🔍 字段解释:

列名 含义 说明
USER 进程所属用户 谁运行的这个程序
PID 进程号(Process ID) 🎯 最重要!每个进程的唯一编号
%CPU CPU 占用率 消耗了多少 CPU 算力
%MEM 内存占用率 消耗了多少内存
VSZ 虚拟内存大小 程序"理论上"能用的最大内存
RSS 实际物理内存 程序真正占用的内存(Resident Set Size)
TTY 终端编号 pts/0 表示远程终端,? 表示后台服务
STAT 进程状态 S=睡眠,R=运行,Z=僵尸,s=会话领导者
START 启动时间 这个进程什么时候开始的
TIME 累计 CPU 时间 这个进程占用了多少 CPU 时间
COMMAND 命令行 运行的什么程序

🎯 PID 是进程的唯一身份证号! 就像每个人的身份证号一样,每个运行的程序都有一个唯一的 PID,后面我们要用 PID 来"杀掉"进程。


3.2 管道符过滤:ps aux | grep

ps aux 列出几百行信息,怎么快速找到特定的进程?这就要用到 Linux 最伟大的发明——管道符 |

管道符的作用:把前面命令的输出,传递给后面的命令去处理。

zhangsan@sre-server:~$ ps aux | grep nginx

📺 模拟的系统输出结果:

root      1234  5.2  0.8  98765 123456 ?        Ssl  10:01  25:45 /usr/sbin/nginx
root      5678  0.0  0.0   8765   1234 pts/0    S+   14:10   0:00 grep nginx

🔍 解释:

  • 第一行:真正的 nginx 进程,PID 是 1234
  • 第二行:就是我们自己敲的 grep nginx 命令!它把自己也过滤出来了!

⚠️ 常见问题:为什么 grep 总是多出一条?答案就在这里——因为 grep 命令本身也是一个进程,它包含 “nginx” 这个关键字(虽然只是在命令参数里)。


3.3 进阶过滤:grep -v grep

如果想把 grep 自己过滤掉,可以加上 grep -v grep

zhangsan@sre-server:~$ ps aux | grep nginx | grep -v grep

📺 模拟的系统输出结果:

root      1234  5.2  0.8  98765 123456 ?        Ssl  10:01  25:45 /usr/sbin/nginx

完美!只剩下真正的 nginx 进程了!


第四步:运维的"手术刀"(kill)

当一个程序卡死、无响应、甚至开始"发疯"占用大量资源时,我们就需要"杀掉"它。这就是运维的"手术刀"——kill 命令。

4.1 温柔结束:kill(正常信号)

kill 进程号 相当于给程序发送一个"温柔通知":请自行关闭,给程序一点时间料理后事(保存数据、关闭文件等)。

# 先找到 PID(比如 nginx 的 PID 是 1234)
zhangsan@sre-server:~$ ps aux | grep nginx | grep -v grep
root      1234  5.2  0.8  98765 123456 ?        Ssl  10:01  25:45 /usr/sbin/nginx

# 温柔地杀掉它
zhangsan@sre-server:~$ kill 1234

# 验证一下
zhangsan@sre-server:~$ ps aux | grep nginx | grep -v grep
# (无输出,说明已经成功关闭)

4.2 强制击杀:kill -9(必杀技)

如果程序"装死"不响应普通 kill 信号,就需要动用"大招"——kill -9 进程号。这相当于直接拔电源,强制系统回收资源。

⚠️ 警告-9 信号会让程序瞬间消失,不会保存任何数据!数据库等有状态服务被这样杀掉,可能导致数据丢失或文件损坏!

# 某些程序(比如卡死的 Python 脚本)普通 kill 杀不掉
zhangsan@sre-server:~$ ps aux | grep python
root     99999  99.9  0.5  12345  67890 ?        R   14:20 500:00 python3 my_script.py

# 尝试普通 kill(可能无效)
zhangsan@sre-server:~$ kill 99999

# 等几秒再查看
zhangsan@sre-server:~$ ps aux | grep python
root     99999  99.9  0.5  12345  67890 ?        R   14:20 500:00 python3 my_script.py
# 还在运行!它"装死"了!

# 动用必杀技
zhangsan@sre-server:~$ kill -9 99999

# 再验证
zhangsan@sre-server:~$ ps aux | grep python
# (无输出,已经被彻底抹杀)

4.3 kill 的信号家族

kill 不仅仅是"杀掉",它其实是一个信号发送工具。最常用的几个信号:

信号编号 信号名 作用 适用场景
1 SIGHUP 重新加载配置 修改了 Nginx 配置后希望重载
15 SIGTERM 正常终止(默认) 给程序一个优雅退出的机会
9 SIGKILL 强制杀死 程序卡死、无响应时的最后手段

💡 企业经验:永远先尝试 kill 进程号(默认发送 SIGTERM)!只有确认程序真的"装死"了,再用 kill -9


四、💥 新手踩坑与排错记录

这周涉及到对系统进程的"生杀大权",非常容易搞出乌龙:

🚨 避坑 1:看到 free 内存很少就慌了?

现象

zhangsan@sre-server:~$ free -h
              total        used        free      shared  buff/cache   available
Mem:           31Gi       28Gi       123Mi       123Mi        10Gi        22Gi

“free 只有 123Mi!这服务器要炸了!”

原因分析

这是 Linux 最让人"误解"的地方。很多新手看到 free 只有几十兆,以为内存要满了。

其实不然!Linux 的内存管理哲学是——“不用白不用”。它会把大量空闲内存拿来做缓存(buffer/cache),以加快文件读取速度。这些缓存可以随时回收给新程序使用!

正确看法

重点看 available(可用内存)这一列!只要 available 还足够,系统就很健康。

字段 含义
free 完全空闲的内存
buff/cache 被用作缓存的内存(可以回收)
available 真正可用的内存 = free + 可回收的 cache

经验总结

  • free 很少是正常的!
  • buff/cache 越多越好(说明系统在加速读取)
  • 只要 available 不告急,就完全没问题!

🚨 避坑 2:用 grep 查进程,为什么总是多出一条?

现象

zhangsan@sre-server:~$ ps aux | grep nginx
root      1234  5.2  0.8  98765 123456 ?        Ssl  10:01  25:45 /usr/sbin/nginx
root      5678  0.0  0.0   8765   1234 pts/0    S+   14:10   0:00 grep nginx

明明没有运行 Nginx,却还是出现了两条结果!

原因分析

因为 ps aux | grep nginx 这个命令本身就是一个进程——grep nginx

它包含 “nginx” 这个关键字,所以把自己也给过滤出来了。

正确做法

进阶使用 grep -v grep,把 grep 自己过滤掉:

zhangsan@sre-server:~$ ps aux | grep nginx | grep -v grep
root      1234  5.2  0.8  98765 123456 ?        Ssl  10:01  25:45 /usr/sbin/nginx

完美!只显示真正的 nginx 进程!


🚨 避坑 3:滥用 kill -9

现象

很多新手觉得 kill -9 杀得快、杀得爽,遇到任何卡顿就喜欢直接 -9

# 看到 MySQL 有点慢
zhangsan@server:~$ kill -9 1234
# MySQL 被瞬间蒸发...

危害分析

信号 效果 风险
kill PID 发送 SIGTERM,程序可优雅退出 ✅ 安全
kill -9 PID 发送 SIGKILL,瞬间蒸发 ⚠️ 数据丢失、文件损坏

对于数据库(MySQL、PostgreSQL)、消息队列(Redis、RabbitMQ)等有状态服务,直接 -9 可能导致:

  • 正在写入的数据丢失
  • 索引文件损坏
  • 事务中断
  • 下次启动需要漫长的修复

经验总结

场景 推荐做法
普通程序卡死 kill PID,等 5 秒
确认无响应 kill -9 PID
数据库/队列 永远先尝试 systemctl restart xxx
找不到 PID pkill -f 程序名killall 程序名

五、下周预告

现在我们已经能掌控正在运行的程序了。但是,如果我们要自己安装一个像 Nginx 或 MySQL 这样的持久化后台服务,该怎么管理它们的开机自启呢?

下周,我们将进入 SRE 极度核心的篇章:系统服务管理 (systemctl) 与软件包归档 (tar)。我们将亲手部署并管理第一个后台服务——

  • systemctl:如何启动、停止、重启服务?
  • 如何让服务开机自动运行?
  • 如何查看服务日志排错?
  • tar:如何打包和解压安装包?

下期见! 🎯


作者:零基础 SRE 实战学员 | 每周一更,记录从 0 到 1 的云运维成长之路

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐