4、进程管理与系统监控:从查看到调优,把脉你的服务器

进程管理,说白了就是跟操作系统里的“活人”打交道。每个程序跑起来就是一个进程,它们抢CPU、占内存、争IO,乱成一锅粥的时候,你就得站出来当那个“交警”。

我刚开始做运维那会儿,最怕的就是线上服务突然变慢。老板站背后问“咋回事”,我对着黑乎乎的终端只能瞎猜。后来才明白,不是工具不好使,是我没用好。今天咱们就把这些看家本事捋一遍。

核心思路:先看整体负载(uptime),再查进程详情(ps/top),最后定位瓶颈(vmstat/iostat)。别一上来就翻日志,那是最后一步。

4.1 进程查看:你得知道谁在干活

4.1.1 ps:静态快照,一锤子买卖

ps 命令就像拍照片,你按下快门那一瞬间,进程是什么样就是什么样。我个人习惯用 ps aux,这个组合能看全所有用户的进程,而且输出格式比较友好。

# 查看所有进程,带完整命令行
ps aux

# 只看某个进程,比如 nginx
ps aux | grep nginx

# 想看进程树,父子关系一目了然
ps axjf

输出里有个 STAT 列,我重点说一下:

状态码 含义 常见场景
R Running / Runnable 正在跑或排队等CPU
S Sleeping(可中断) 等IO完成,比如读磁盘
D Uninterruptible Sleep 等磁盘IO,kill -9都杀不掉
Z Zombie(僵尸) 子进程死了,父进程没收尸
T Stopped 被暂停了,比如按了Ctrl+Z

一个小技巧:看到大量 D 状态进程,别急着 kill,先检查磁盘是不是挂了。我曾经在 NFS 挂载点出问题时,满屏都是 D 状态,重启都没用,最后是修复了远程存储才恢复。

4.1.2 top:动态监控,实时刷新

top 是动态的,默认3秒刷新一次。它像是一个实时仪表盘,CPU、内存、负载、进程列表全在上面。

# 直接运行
top

# 按 CPU 使用率排序(进入 top 后按 P)
# 按内存使用率排序(进入 top 后按 M)
# 只看某个用户的进程(进入 top 后按 u,输入用户名)

top 界面上半部分有几个关键指标:

  • load average:1分钟、5分钟、15分钟的平均负载。如果1分钟远大于15分钟,说明负载在飙升。
  • %us / %sy:用户态CPU和系统态CPU。%sy 太高,说明内核在忙,可能是系统调用太频繁。
  • %wa:IO等待。这个值如果持续超过30%,磁盘大概率是瓶颈。

注意:别把 CPU 使用率和系统负载划等号。负载高不一定 CPU 忙,也可能是大量进程在等 IO。我见过有人看到负载高就加 CPU,结果问题根本没解决。

4.1.3 htop:top 的升级版,更直观

htop 不是系统自带的,但强烈建议装上。它支持鼠标操作、颜色区分、树形视图,看着舒服多了。

# 安装(CentOS)
yum install htop -y

# 安装(Ubuntu)
apt install htop -y

# 运行
htop

htop 里我最喜欢的功能是 F5 树形视图,能清楚看到哪个进程是哪个进程生出来的。排查僵尸进程时特别好用——找到父进程,直接干掉它,子进程就由 init 收养了。

4.2 进程控制:该杀就杀,该让就让

4.2.1 kill:发信号,不只是“杀死”

kill 这个名字有点误导人,它其实是给进程发信号。默认信号是 SIGTERM (15),让进程自己收拾干净再退出。实在不行才用 SIGKILL (9),直接暴力砍掉。

# 优雅终止(推荐)
kill 1234

# 强制杀死(最后手段)
kill -9 1234

# 重载配置(比如 nginx 热加载)
kill -HUP 1234

# 暂停进程
kill -STOP 1234

# 继续运行
kill -CONT 1234

我的习惯:先 kill -15,等5秒,不行再 kill -9。直接上 -9 容易丢数据,尤其是数据库进程。有一次我手快 kill -9 了一个 MySQL 进程,结果恢复花了半小时。

4.2.2 nice 与 renice:给进程排优先级

CPU 资源不够分的时候,谁先跑谁后跑,由 nice 值决定。范围是 -20 到 19,值越低优先级越高。普通用户只能调高(更 nice),root 可以调低(更霸道)。

# 启动时指定 nice 值(优先级较高)
nice -n -5 ./myapp

# 调整正在运行的进程(把 PID 1234 的优先级调低)
renice 10 -p 1234

实际场景中,我会把后台批处理任务的 nice 值调高(比如 10),让它们别跟线上服务抢 CPU。反过来,核心数据库进程我会调低 nice 值(比如 -5),保证响应速度。

4.3 系统负载分析:找到真正的瓶颈

4.3.1 uptime:看一眼就知道服务器累不累

uptime 是最简单的命令,输出只有一行,但信息量很大。

$ uptime
 14:32:10 up 120 days,  3:15,  2 users,  load average: 0.45, 0.62, 0.71

三个负载值分别对应1、5、15分钟的平均值。怎么判断是否正常?

  • 负载值 < CPU 核心数:正常,资源充裕。
  • 负载值 ≈ CPU 核心数:快满了,需要关注。
  • 负载值 > CPU 核心数 * 2:已经过载,必须处理。

举个例子,一台 4 核服务器,负载 8.0,说明平均每个核有 2 个进程在排队。这时候用户访问肯定会觉得卡。

4.3.2 vmstat:虚拟内存和系统整体状况

vmstat 是我排查性能问题时用的最多的命令之一。它把 CPU、内存、IO 的情况浓缩在一张表里。

# 每2秒输出一次,共输出5次
vmstat 2 5

输出示例:

procs memory swap io system cpu
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 123456 7890 45678 0 0 100 50 200 1500 30 10 60 0 0

关键列解读:

  • r(procs):正在排队等 CPU 的进程数。如果这个值持续大于 CPU 核心数,说明 CPU 不够用。
  • b(procs):处于不可中断睡眠的进程数。如果这个值一直大于0,IO 大概率有问题。
  • si / so(swap):从磁盘交换进/出的内存量。如果这两个值不是0,说明物理内存不够了,系统在频繁换页,性能会急剧下降。
  • wa(cpu):IO 等待时间。超过30%就要查磁盘了。

避坑指南:我曾经遇到一个 Java 应用,vmstat 显示 si/so 持续不为0,但 free 命令看内存还有剩余。后来发现是 JVM 的堆外内存没算进去,加上 GC 参数不合理,导致系统不断 swap。调了 JVM 参数后,si/so 立刻归零。

4.3.3 iostat:磁盘到底行不行

当 vmstat 的 wa 偏高时,就该用 iostat 看看具体是哪块磁盘在拖后腿。

# 查看所有磁盘的 IO 统计,每2秒刷新一次
iostat -x 2

重点关注这几个指标:

指标 含义 健康值
%util 磁盘忙绿时间百分比 < 70% 正常,> 90% 危险
await IO 请求平均等待时间(ms) SSD < 5ms,机械盘 < 20ms
svctm IO 请求平均服务时间(ms) 越接近 await 越好
r/s / w/s 每秒读/写请求数 取决于磁盘规格

如果 %util 接近100%但 r/s 不高,说明磁盘本身性能不行,该换了。如果 await 远大于 svctm,说明 IO 队列太长,请求在排队。

4.4 知识体系总览

下面这张图把本章的核心命令和它们之间的关系串起来了。你可以把它当作排查问题的路线图。

进程管理与系统监控知识体系 进程管理与系统监控:排查路线图 系统变慢 / 报警 uptime:看负载 CPU 高?→ top / htop IO 高?→ iostat vmstat:全面诊断 ps aux → 找进程 kill / nice → 干预 看 %util / await 排查磁盘 / 换硬件 先看整体,再查局部,最后动手干预 别跳过 uptime 和 vmstat 直接翻日志

4.5 实战排查流程

最后,我总结一个实际排查的步骤,你遇到问题直接照着来:

  1. 第一步:跑 uptime,看负载是否异常。如果负载正常,可能是应用层的问题,不是系统瓶颈。
  2. 第二步:跑 vmstat 1 5,看 r、b、wa、si/so 哪个指标异常。
  3. 第三步:如果 wa 高,跑 iostat -x 1 定位磁盘;如果 r 高,跑 top 看哪个进程在吃 CPU。
  4. 第四步:用 ps aux 找到具体进程,确认是不是预期内的程序。
  5. 第五步:根据情况用 kill 终止异常进程,或用 renice 调整优先级。

这套流程我用了好多年,从几十台的小集群到上千台的大规模环境,基本没失手过。你把它记熟了,遇到线上故障就不会慌。