Linux 性能调优系列 (二):掌握基础性能监控命令
1 | 作者:李晓辉 |
这是 Linux性能调优系列第二篇。上一篇我们讲完性能调优基础理论,学会了USE分析法的排查思路。
思路有了,那用什么工具拿到服务器真实指标呢?这一篇就来讲系统自带的基础监控命令。不需要装任何额外软件,系统开箱即用,线上排错天天都会敲。
做系统监控,说白了就是收集系统各项数据,看看CPU、内存、磁盘、网络这些资源现在跑的怎么样。一方面帮我们排查线上故障,另一方面验证我们的调优改动到底有没有生效。
很多人不知道,Linux内核里面维护了一大堆内核计数器。每当发生磁盘读写、进程系统调用、中断这些事件的时候,对应的计数器数值就会往上加。我们用的ps、top这些命令,本质就是读取内核的这些计数器,整理成人类看得懂的输出。大部分统计信息普通普通用户就可以查看,不需要root权限。
进程监控工具 ps
💡重点:
ps拿到的是执行命令那一瞬间的静态快照,执行完就退出,不会自动刷新。
玩 Linux 的 ps 命令的时候,你会发现网上有两类写法:一类参数不带短横杠 -,一类参数带短横杠 -,这分别对应 BSD 风格与 POSIX 标准风格。
- BSD 风格(无横杠,来自BSD Unix)
代表命令:ps aux
- 参数前面不加
-,比如aux,而不是-aux - 源自 BSD 版本的 Unix,是运维圈子流传最广、教程最常见的写法
- 输出格式偏向人性化,列布局适合日常人工阅读
- POSIX 标准风格(带横杠,IEEE标准)
代表命令:ps -ef
- 参数前面必须带上短横杠
-,符合 POSIX 可移植标准 - 属于统一Unix规范,不同Unix/Linux之间兼容性更好,适合写shell脚本
-e显示全部进程、-f完整格式、-o自定义字段,都是POSIX标准参数
查看服务器全部进程
BSD风格,运维最常用:
1 | ps aux |
a:展示所有用户的进程u:输出更友好的用户可读格式x:把没有绑定终端的后台守护进程也打印出来
执行出来你会看到很多进程的TTY那一列是问号?,这就代表这个进程是后台服务,没有登录终端,比如systemd、sshd这类守护进程。
输出看看:
1 |
|
ps输出关键字段解释
1 | USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND |
USER:运行进程的用户名PID:进程ID,杀进程、调优先级全靠它%CPU:⚠️注意!这个是进程整个生命周期的CPU平均使用率,不是此刻瞬间CPU占用!想看瞬时CPU不要看ps,要用top%MEM:该进程RSS占整机物理内存的百分比VSZ:虚拟内存大小(KB),对应top里面的VIRTRSS:常驻集大小,进程实际占的物理内存,单位KB,不包含交换出去的内存TTY:关联终端,?代表后台守护进程STAT:进程状态码(R/S/T/I等)START:进程启动时间TIME:进程从启动到现在累计消耗的CPU总时间,看的是历史总的工作量,不是瞬时占用COMMAND:执行的完整命令
POSIX标准写法:
1 | ps -ef |
-e:列出系统里面每一个进程-f:完整格式输出,会多出PPID父进程ID
输出看看:
1 | [root@localhost ~]# ps -ef | more |
| 字段 | 说明 |
|---|---|
UID | 进程运行的用户ID,root代表root用户 |
PID | 进程ID,操作进程的唯一标识 |
PPID | 父进程ID,这个进程由哪个进程创建。追查进程父子、僵尸进程就看这一列 |
C | CPU 调度利用率计数,范围 0‑99,数值越高代表进程近期消耗 CPU 越多。⚠️不是 CPU 百分比,是历史加权统计,内核线程大多显示 0;现在排查性能一般不依赖此字段,优先使用 top 看瞬时占用。 |
STIME | 进程启动的时间;如果跨天会显示日期 |
TTY | 进程关联终端;?代表无终端,后台守护进程 |
TIME | 进程累计占用CPU总时间,是历史累加值,不是瞬时CPU使用率 |
CMD | 启动进程的命令,内核线程会用方括号 [] 包裹 |
✨小实战:当你要追查僵尸进程、看进程父子继承关系的时候,就用
ps -ef,通过PPID可以看到是谁拉起的这个进程。
只想看某一类进程
比如我只想看sshd相关进程,直接用‑C参数,按程序名字过滤:
1 | [root@localhost ~]# ps -C sshd |
如果你手上已经知道程序名,先用pidof抓PID,再传给ps查看详情:
1 | [root@localhost ~]# ps -p $(pidof sshd) |
自定义输出列,按资源排序
线上经常要找吃内存最多的进程,我们可以自己指定输出哪些列,再做排序。
示例:只打印PID、内存占比、执行命令,按照内存从大到小排序,取前10行
1 | [root@localhost ~]# ps axo pid,pmem,cmd --sort -pmem | head |
POSIX等价写法:
1 | [root@localhost ~]# ps -eo pid,pmem,cmd --sort -pmem | head |
-o:自定义要展示的字段--sort -pmem:按内存占比降序,减号代表降序
长格式查看,看进程状态、nice优先级:
1 | [root@localhost ~]# ps -ly -C sshd |
| 字段 | 说明 |
|---|---|
S | 进程状态码。S代表可中断睡眠;R运行;T停止;I空闲内核线程 |
UID | 运行该进程的用户ID,0代表root用户 |
PID | 进程ID |
PPID | 父进程ID,由哪个进程创建当前进程 |
C | CPU调度利用率计数(0‑99),数值越高近期CPU消耗越多;不是百分比,历史加权统计,性能排查基本不看此字段 |
PRI | 进程调度优先级,由系统内核自动计算;数值越小优先级越高 |
NI | nice友好值,用户可手动调整,范围‑20 ~ 19;值越小越容易拿到CPU时间,会间接影响PRI |
RSS | 常驻内存大小,单位KB,进程实际占用物理内存 |
SZ | 虚拟内存大小,单位KB,进程全部虚拟地址空间大小 |
WCHAN | 进程当前正在等待的内核函数;poll_s代表进程正在poll休眠等待事件;不为空说明进程处于睡眠状态 |
TTY | 绑定终端;?表示无终端,后台守护进程 |
TIME | 进程累计消耗CPU总时间,历史累加,非瞬时CPU占用 |
CMD | 进程对应的程序命令 |
💡实战小提示:
-l开启长格式,展示调度相关信息;‑y选项会不显示高级标志字段,让RSS直接以KB展示,可读性更好。- WCHAN列非常适合看进程卡在哪个内核行为上,如果这个字段为空,代表进程此刻正在CPU上运行(R状态)。
实时进程监控 top
ps是拍一张照片,top相当于实时录像,会持续刷新屏幕,观察资源的动态变化,是运维人手必备工具。
直接敲命令进入交互界面:
1 | top - 17:25:41 up 19 min, 2 users, load average: 0.06, 0.02, 0.00 |
top表头解释
我们分两块来看,第一块是表头
| 行号 | 输出内容 | 说明 |
|---|---|---|
| 第1行 | top - 17:25:41 up 19 min, 2 users, load average: 0.06, 0.02, 0.00 | 系统时间:17:25:41;已开机运行19分钟;登录2个用户; load average:1分钟、5分钟、15分钟系统平均负载 |
| 第2行 | Tasks: 241 total, 1 running, 240 sleeping, 0 stopped, 0 zombie | 进程统计:总共241个进程,1个正在运行,240个睡眠,0个停止,0个僵尸进程 |
| 第3行 | %Cpu(s): 0.0 us, 0.2 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.1 hi, 0.1 si, 0.0 st | CPU整体占比: us 用户态;sy内核态;ninice调整进程;id空闲; wa等待IO;hi硬件中断;si软件中断;st虚拟化被宿主机偷走CPU时间 |
| 第4行 | MiB Mem : 7903.1 total, 7464.2 free, 514.4 used, 123.8 buff/cache | 物理内存,单位MiB:总内存、空闲内存、已使用内存、缓冲区/缓存内存 |
| 第5行 | MiB Swap: 8032.0 total, 8032.0 free, 0.0 used. 7388.7 avail Mem | 交换分区;avail Mem真正可分配给应用的可用内存,判断内存压力核心指标 |
第二块来解释一下下面的表头含义
| 字段 | 说明 |
|---|---|
PID | 进程ID |
USER | 运行进程的用户名 |
PR | 内核计算的调度优先级,数值越小优先级越高 |
NI | nice值,用户可修改,范围‑20~19,越小越优先获取CPU |
VIRT | 虚拟内存(KB),包含物理内存、共享库、交换页,进程全部地址空间 |
RES | 常驻物理内存(KB),进程实际占用RAM,不含交换出去的内存 |
SHR | 共享内存(KB),可被多个进程共享;进程独占内存≈RES‑SHR |
S | 进程状态:R运行、S可中断睡眠、D不可中断睡眠、T停止、I空闲内核线程 |
%CPU | 本次刷新间隔内瞬时CPU占用,按单个CPU核心百分比统计,排查CPU热点主要看这里 |
%MEM | 该进程占整机物理内存的百分比 |
TIME+ | 进程累计CPU时间,精度到百分之一秒,进程从启动到现在总共消耗CPU时长 |
COMMAND | 启动该进程的程序命令 |
💡实战小提示:
- 按下
1可以展开,查看每一颗CPU核心单独的使用率;%CPU可以超过100%,代表进程在使用多个CPU核心。
很多写脚本的时候需要拿top的输出数据,不要直接交互式跑,用批处理模式。
-b批处理输出,‑n 1代表只采样一次就退出,输出快照,适合管道、脚本处理。
1 | [root@localhost ~]# top -b -n 1 | more |
top高频实战快捷键
| 按键 | 实战用途 |
|---|---|
1 | 把总的CPU展开,显示每一个逻辑核单独使用率,排查单核心打满特别好用 |
Shift+P | 按CPU使用率降序,默认排序 |
Shift+M | 切换成按内存使用率降序,瞬间找出吃内存大户 |
Shift+H | 显示线程,很多Java程序排查要打开看线程数量 |
S | 修改刷新间隔,比如输入0.5就是半秒刷新一次,默认3秒 |
K | 输入PID,直接给进程发信号,可以杀死异常进程 |
R | 输入PID,修改进程nice优先级 |
Shift+W | 把你当前top的显示配置保存,下次打开top直接沿用你的设置 |
F | 自定义屏幕上显示哪些列,还可以指定用哪一列做排序依据 |
Q | 退出top |
内存状态监控 free
free命令用来查看整机物理内存和交换分区的整体概况。
🚨新手最大的坑:很多人看到free那一列数字很小就慌,以为内存爆了,其实完全不是!
Linux会把空闲内存拿来做磁盘缓存,加速读写。判断内存够不够,一定要看available这一列,不要看free!
1 | [root@localhost ~]# free -h |
| 字段 | 说明 |
|---|---|
total | 总内存/总交换空间大小,整机硬件配置的总容量 |
used | 已经被程序、内核占用的内存;包含进程内存、共享内存、buff/cache缓存 |
free | 完全空闲、还没有被任何程序/缓存占用的裸内存。 ⚠️不要以此判断内存不足,Linux会主动拿空闲内存做缓存,free很小属于正常现象。 |
shared | 多个进程之间共享使用的内存大小,比如共享库、tmpfs临时文件系统占用内存 |
buff/cache | 缓冲区 + 页缓存总和。内核用来加速磁盘读写;当应用需要内存的时候,内核可以快速回收这部分内存给业务使用。 |
available | ✅判断内存压力最重要指标。估算可以分配给新进程的内存总量,包含free,加上可以回收的buff/cache。看内存够不够优先看这一列,不要看free。 |
💡实战小提示
Mem行代表物理内存RAM;Swap行代表交换分区。- Swap的
used数值持续上涨,代表物理内存不足,系统开始使用交换,性能会下降。-h输出是二进制单位 Gi/Mi;如果使用-H参数,则为厂商十进制 GB/MB。
如果你想持续盯着内存变化,每秒刷新一次:
1 | [root@localhost ~]# free -h |
按Ctrl+C结束。
vmstat:一站式综合系统状态统计
vmstat 属于procps‑ng工具集,一条命令同时输出内存、swap、磁盘IO、中断、上下文切换、CPU状态。
⚠️非常重要:输出的第一行数据,是服务器开机到现在全部的平均值,不是当前实时状态!分析实时数据请忽略第一行,看后面采样输出。
语法:vmstat [选项] 采样间隔秒数 采样次数
示例:每1秒输出一次,一共输出3次,内存单位使用MiB
1 | [root@localhost ~]# vmstat -S M 1 3 |
vmstat 输出表头字段详解
| 分类 | 字段 | 说明 |
|---|---|---|
| procs | r | 等待CPU调度运行的进程数量。数值持续偏高,代表CPU资源紧张,进程在排队 |
| b | 处于不可中断睡眠状态的进程数,大多是在等待磁盘IO;数值高代表IO阻塞严重 | |
| memory | swpd | 已经写入交换分区的内存大小(MiB)。数值持续上涨,说明物理内存不足,发生内存换出 |
| free | 完全空闲物理内存大小 | |
| buff | 用作块设备缓冲区的内存,存放块设备原始块数据 | |
| cache | 页缓存内存,文件系统缓存,加速文件读写,内存紧张时内核可以回收 | |
| swap | si | 每秒从swap换入内存的页数。从交换分区读回物理内存 |
| so | 每秒向swap换出内存的页数。物理内存不足时,把内存页写到交换分区。si/so持续不为0代表内存压力大 | |
| io | bi | 每秒从块设备读取的块数量(读磁盘) |
| bo | 每秒向块设备写入的块数量(写磁盘) | |
| system | in | 每秒硬件中断次数,硬件设备向内核发起中断请求 |
| cs | 每秒上下文切换次数。进程之间切换CPU,数值很高代表系统频繁切换进程,会带来性能损耗 | |
| cpu | us | 用户态CPU占比,业务应用程序消耗CPU时间百分比 |
| sy | 内核态CPU占比,内核、系统调用消耗CPU时间百分比 | |
| id | CPU空闲时间百分比 | |
| wa | IO等待CPU占比,CPU空闲但是进程卡在等待磁盘IO;wa高代表磁盘IO瓶颈 | |
| st | 被虚拟化宿主机偷走的CPU时间,云虚拟机才会出现该指标 | |
| gu | 运行KVM客户机代码占用CPU时间,KVM宿主机才会看到数值 |
💡实战小提示
vmstat默认单位是KiB,加上-S M才会切换成MiB,看示例里数字 7466 就是7466MiB内存;- 重点观察:
r、b判断CPU/IO排队;si so判断内存压力;wa判断磁盘IO瓶颈;cs观察上下文切换。
文件系统与磁盘空间工具
线上磁盘占满会直接导致业务报错,甚至服务起不来,下面几个命令日常高频使用。
lsblk:看磁盘、分区的树状结构
想知道服务器有几块盘,分区、挂载点对应关系,用lsblk。
1 | [root@localhost ~]# lsblk -p |
‑p打印设备完整绝对路径,加上‑f还可以打印文件系统UUID、文件系统类型。
findmnt:查看挂载详细信息
查看全部挂载点,文件系统类型、挂载参数。
1 | [root@localhost ~]# findmnt |
太多了,只想看某一块设备:
1 | [root@localhost ~]# findmnt /dev/nvme0n1p2 |
‑s选项,直接读取/etc/fstab里面的挂载配置。
1 | [root@localhost ~]# findmnt -s |
df:查看各个挂载盘占用空间
1 | [root@localhost ~]# df -hT |
-h:二进制GiB/MiB单位,操作系统标准-T:额外打印文件系统类型(xfs/ext4)
注意区分参数:
‑H是十进制SI单位,就是硬盘厂商宣传用的1GB=1000MB,和‑h不要搞混。
du:统计目录真实占用磁盘大小
递归统计目录下面所有文件占用磁盘。
1 | [root@localhost ~]# du -h /usr/share | more |
目录层级多的时候刷屏,加上‑s只输出汇总总和,不打印子文件夹明细。
示例:一次性看/etc /boot /var这几个目录各自占用多少磁盘
1 | [root@localhost ~]# du -sh /etc /boot /var |
GNOME System Monitor 图形监控工具
如果是带GNOME桌面的服务器,可以打开系统监视器,图形界面工具,功能等价ps+top+df,带历史趋势曲线图。
分为3个选项卡:
- Processes(进程):图形化进程列表,可以点击表头排序,右键终止/杀死进程,调整进程优先级,设置CPU亲和性,还可以查看进程内存映射;
- Resources(资源):图表展示每颗CPU历史曲线、内存swap、网络收发、磁盘读写的历史走势,看波动很直观;
- File Systems(文件系统):图形化看各个磁盘分区容量占用。

⚠️注意:生产服务器绝大多数没有图形桌面,图形工具只能本地测试机玩玩,线上全部用上面命令行工具。
写在最后
本篇全部都是系统自带工具,不需要额外装任何软件包。简单梳理下各自适合的场景:
ps:拍进程静态快照,排查进程父子关系top:实时看进程瞬时CPU、内存占用,交互式观察动态变化free:整机内存总览,记住看available,不要被free列迷惑vmstat:一站式看整机CPU、内存、swap、IO、中断上下文切换综合状态lsblk / df / du:磁盘设备、挂载、磁盘空间排查
下一篇预告:Linux性能调优系列(三),我们讲解sysstat工具包 mpstat、iostat、pidstat、sar,以及PCP+Grafana实现长期性能数据采集与可视化。