Linux 系统监控实战:从命令行到 Python 脚本全栈指南
实验环境 :华为云 FlexusX x2e.8u.16g × 4 节点(ecs-3bfd)
操作系统 :Ubuntu 24.04 Server 64bit | 内核 6.8.0-106-generic
CPU :AMD EPYC (8 vCPUs, 4 cores, AVX-512) | 内存:16 GiB
节点 公网 IP 私有 IP 用途 ecs-3bfd-0001 113.44.141.34 192.168.0.185 主实验节点 ecs-3bfd-0002 120.46.93.225 192.168.0.70 辅助节点 ecs-3bfd-0003 120.46.222.203 192.168.0.2 辅助节点 ecs-3bfd-0004 124.70.110.214 192.168.0.112 辅助节点
目录
- [Linux 监控体系总览](#Linux 监控体系总览)
- [top --- 实时进程监控](#top — 实时进程监控)
- [vmstat --- 虚拟内存统计](#vmstat — 虚拟内存统计)
- [lsof --- 列出打开的文件](#lsof — 列出打开的文件)
- [tcpdump --- 网络包分析器](#tcpdump — 网络包分析器)
- [netstat --- 网络状态统计](#netstat — 网络状态统计)
- [htop --- 交互式进程监控](#htop — 交互式进程监控)
- [iotop --- 磁盘 I/O 监控](#iotop — 磁盘 I/O 监控)
- [iostat --- I/O 统计报告](#iostat — I/O 统计报告)
- [IPTraf-ng --- 实时局域网 IP 监控](#IPTraf-ng — 实时局域网 IP 监控)
- [NetHogs --- 进程级网络带宽监控](#NetHogs — 进程级网络带宽监控)
- [iftop --- 网络带宽实时监控](#iftop — 网络带宽实时监控)
- [sysv-rc-conf / systemctl --- 服务管理](#sysv-rc-conf / systemctl — 服务管理)
- [Nagios --- 企业级监控平台](#Nagios — 企业级监控平台)
- [Python 监控脚本实战](#Python 监控脚本实战)
- 监控工具对比总结
1. Linux 监控体系总览
Linux 系统监控可分为四个维度:
┌─────────────────────────────────────────────────────────────────┐
│ Linux 系统监控体系 │
├────────────┬────────────┬────────────────┬─────────────────────┤
│ CPU 监控 │ 内存监控 │ 磁盘 I/O 监控 │ 网络流量监控 │
│ top │ top/free │ iostat │ iftop / nethogs │
│ htop │ vmstat │ iotop │ netstat / ss │
│ vmstat │ /proc/ │ df/du │ tcpdump │
│ mpstat │ meminfo │ lsof │ IPTraf-ng │
├────────────┴────────────┴────────────────┴─────────────────────┤
│ 统一监控平台 │
│ Nagios / Prometheus + Grafana / Zabbix │
└─────────────────────────────────────────────────────────────────┘
监控工具安装
bash
# 一键安装所有实验工具
apt-get update && apt-get install -y \
htop \
sysstat \
iotop \
iftop \
nethogs \
tcpdump \
lsof \
net-tools \
iptraf-ng \
nagios4 nagios-plugins
# 启用 sysstat 定时采集(每 10 分钟)
systemctl enable --now sysstat
sed -i 's/false/true/' /etc/default/sysstat
2. top --- 实时进程监控
top (Table Of Processes) 是 Linux 最经典的实时进程监控工具,每 3 秒刷新一次,显示系统当前资源占用情况。
2.1 实验服务器实际输出
[root@ecs-3bfd-0001 ~]# top -bn1
top - 16:14:57 up 3 min, 2 users, load average: 0.01, 0.03, 0.00
Tasks: 182 total, 1 running, 181 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 1.2 sy, 0.0 ni, 98.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 15131.9 total, 14140.3 free, 599.0 used, 666.9 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 14532.9 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6681 root 20 0 11932 5768 3632 R 9.1 0.0 0:00.01 top
1 root 20 0 22632 14028 9620 S 0.0 0.1 0:02.46 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 pool_wo+
2.2 输出字段详解
头部信息(系统概览):
| 字段 | 说明 | 示例值 |
|---|---|---|
up 3 min |
系统运行时长 | 刚启动 3 分钟 |
load average: 0.01, 0.03, 0.00 |
1/5/15 分钟平均负载 | 8核CPU,<1.0 表示空闲 |
Tasks: 182 total |
总进程数 | 182个进程 |
1 running |
正在运行的进程数 | 只有 top 本身 |
181 sleeping |
休眠进程数 | 正常,大多数进程等待事件 |
0 zombie |
僵尸进程数 | 0 为正常,>0 需排查 |
CPU 字段(%Cpu(s)行):
| 字段 | 含义 | 本机值 |
|---|---|---|
us |
user --- 用户态 CPU 使用率 | 0.0% |
sy |
system --- 内核态 CPU 使用率 | 1.2% |
ni |
nice --- 低优先级进程 CPU | 0.0% |
id |
idle --- CPU 空闲率 | 98.8% |
wa |
iowait --- 等待 I/O 的 CPU 占比 | 0.0% |
hi |
hardware interrupt --- 硬中断 | 0.0% |
si |
software interrupt --- 软中断 | 0.0% |
st |
steal --- 被虚拟机管理程序偷用 | 0.0% |
💡 性能判断依据 :
wa > 10%表示磁盘 I/O 瓶颈;st > 5%表示宿主机 CPU 资源争抢;us + sy > 80%表示 CPU 资源紧张。
内存字段(MiB Mem行):
| 字段 | 含义 | 本机值 |
|---|---|---|
total |
物理内存总量 | 15131.9 MiB ≈ 14.8 GiB |
free |
完全未使用 | 14140.3 MiB(空闲率 93%) |
used |
已使用 | 599.0 MiB |
buff/cache |
内核缓冲区+文件缓存 | 666.9 MiB |
avail Mem |
可用于新进程的内存 | 14532.9 MiB |
进程列表字段:
| 字段 | 含义 |
|---|---|
PID |
进程 ID |
PR |
内核调度优先级(数值越小越高) |
NI |
nice 值,-20 到 +19(越小优先级越高) |
VIRT |
虚拟内存总量(包括未实际分配的) |
RES |
物理内存实际占用(Resident Set Size) |
SHR |
共享内存大小 |
S |
进程状态:R(运行) S(休眠) Z(僵尸) T(停止) |
%CPU |
CPU 占用百分比 |
%MEM |
物理内存占用百分比 |
TIME+ |
进程累计 CPU 时间 |
2.3 常用交互命令
top 运行时快捷键:
1 --- 展开显示每个 CPU 核心的使用率
M --- 按内存使用率排序
P --- 按 CPU 使用率排序(默认)
T --- 按 TIME+ 累计 CPU 时间排序
k --- 杀死指定 PID 进程
r --- 修改进程 nice 值
c --- 显示完整命令行(而非截断)
u --- 只显示指定用户的进程
q --- 退出
space --- 强制立即刷新
d / s --- 修改刷新间隔(秒)
H --- 切换显示线程/进程
W --- 保存当前 top 配置到 ~/.toprc
z --- 彩色显示
x/y --- 高亮排序列和运行中进程
2.4 常用命令行选项
bash
# 每 2 秒刷新,仅显示 root 的进程
top -u root -d 2
# 批量模式输出,采集 5 次(适合脚本调用)
top -bn5 -d 1
# 每 1 秒刷新,显示所有线程(进程内线程级别)
top -H -d 1
# 只监控指定 PID
top -p 1234,5678
# 非交互输出到文件(用于定时采集)
top -bn1 > /var/log/top_snapshot_$(date +%Y%m%d_%H%M%S).log
2.5 负载均值解读(Load Average)
load average: 0.01, 0.03, 0.00
↑ ↑ ↑
1分钟 5分钟 15分钟
本机 8 vCPU,判断标准:
< 8.0 --- 正常,CPU 有富余
8.0 --- 满载,每个核心都有一个任务
> 8.0 --- 超载,有任务在排队等待 CPU
> 16.0 --- 严重超载,系统响应变慢
当前 0.01 / 0.03 / 0.00 → 系统几乎空载(刚启动)
3. vmstat --- 虚拟内存统计
vmstat (Virtual Memory Statistics) 报告进程、内存、分页、块 I/O、陷阱和 CPU 活动的统计信息。
3.1 实验服务器实际输出
[root@ecs-3bfd-0001 ~]# vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
r b swpd free buff cache si so bi bo in cs us sy id wa st gu
0 0 0 14479960 30220 652544 0 0 1908 3743 969 1 0 1 97 1 0 0
0 0 0 14484660 30236 653800 0 0 20 0 756 664 0 0 100 0 0 0
0 0 0 14486880 30244 654852 0 0 0 84 372 397 0 0 100 0 0 0
0 0 0 14489768 30244 655904 0 0 0 0 358 382 0 0 100 0 0 0
0 0 0 14491784 30244 656944 0 0 0 0 351 384 0 0 100 0 0 0
3.2 字段详解
第一行是系统启动以来的累计平均值,从第二行起才是实时采样数据。
procs(进程):
| 列 | 含义 | 本机值 |
|---|---|---|
r |
运行队列中等待 CPU 的进程数 | 0(无排队) |
b |
处于不可中断睡眠中的进程数(等待 I/O) | 0 |
memory(内存,单位 KB):
| 列 | 含义 | 本机值 |
|---|---|---|
swpd |
已使用 swap 空间 | 0(未启用 swap) |
free |
空闲物理内存 | 14,479,960 KB ≈ 13.8 GiB |
buff |
内核缓冲区(buffered I/O) | 30,220 KB ≈ 30 MiB |
cache |
页面缓存(cached I/O) | 652,544 KB ≈ 637 MiB |
swap(交换):
| 列 | 含义 |
|---|---|
si |
从磁盘换入内存的速率(KB/s),非 0 说明内存不足 |
so |
从内存换出到磁盘的速率(KB/s),非 0 说明内存压力大 |
io(I/O,单位 blocks/s):
| 列 | 含义 | 本机值 |
|---|---|---|
bi |
从块设备读入的速率(blocks/s) | 第一行 1908(启动期磁盘读)→后续降至 0 |
bo |
写入块设备的速率(blocks/s) | 第一行 3743→后续 0 |
system(系统调用):
| 列 | 含义 | 本机值 |
|---|---|---|
in |
每秒中断次数(含时钟中断) | 351~969 |
cs |
每秒上下文切换次数 | 384~664(正常系统很低) |
cpu(CPU 使用率百分比):
| 列 | 含义 | 本机值 |
|---|---|---|
us |
用户态 | 0 |
sy |
内核态 | 0~1 |
id |
空闲 | 97~100 |
wa |
I/O 等待 | 0~1 |
st |
虚拟化偷用 | 0 |
gu |
KVM guest 用户态(Ubuntu 24.04 新增) | 0 |
3.3 实用场景
bash
# 持续采样(每秒一次,共 60 次)→ 分析突发问题
vmstat 1 60
# 磁盘统计(-d 模式)
vmstat -d
# 内存统计(活跃/非活跃页面详情)
vmstat -a
# 汇总模式:每 5 秒输出无限次(监控脚本常用)
vmstat 5
# 时间戳模式(-t)便于日志关联
vmstat 1 10 -t
3.4 性能基准参考
健康系统特征:
r < CPU核心数 × 2 --- CPU 不饱和
b = 0 --- 无 I/O 阻塞进程
si = so = 0 --- 无 swap 活动
wa < 5% --- I/O 等待低
cs < 20000 --- 上下文切换正常
告警阈值:
r > CPU核心数 × 3 --- CPU 严重排队
si > 0 持续出现 --- 内存不足,需加内存或减少进程
wa > 20% --- 磁盘 I/O 成瓶颈
cs > 100000/s --- 上下文切换过频(检查是否有大量短任务)
4. lsof --- 列出打开的文件
lsof (List Open Files) 列出系统中所有进程打开的文件(含普通文件、目录、设备、网络套接字、管道)。在 Linux 中,"一切皆文件",因此 lsof 功能极其强大。
4.1 实验服务器实际输出
[root@ecs-3bfd-0001 ~]# lsof -i -n -P | head -20
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 109u IPv4 10622 0t0 TCP *:22 (LISTEN)
systemd 1 root 113u IPv6 10624 0t0 TCP *:22 (LISTEN)
systemd-r 521 systemd-resolve 14u IPv4 5418 0t0 UDP 127.0.0.53:53
systemd-r 521 systemd-resolve 15u IPv4 5419 0t0 TCP 127.0.0.53:53 (LISTEN)
NetworkMa 4495 root 26u IPv4 5764 0t0 UDP 192.168.0.185:68->192.168.0.254:67
chronyd 4713 _chrony 5u IPv4 11015 0t0 UDP 127.0.0.1:323
sshd 5513 root 3u IPv4 10622 0t0 TCP *:22 (LISTEN)
sshd 5513 root 4u IPv6 10624 0t0 TCP *:22 (LISTEN)
uniagentd 5790 root 5u IPv4 12844 0t0 TCP 127.0.0.1:29338 (LISTEN)
uniagentd 5790 root 9u IPv4 13050 0t0 TCP 192.168.0.185:58152->100.125.12.110:33554 (ESTABLISHED)
sshd 6690 root 4u IPv4 17318 0t0 TCP 192.168.0.185:22->120.25.187.184:61105 (ESTABLISHED)
sshd 6692 root 4u IPv4 17322 0t0 TCP 192.168.0.185:22->120.25.187.184:26764 (ESTABLISHED)
4.2 字段说明
| 列 | 含义 | 示例 |
|---|---|---|
COMMAND |
进程名(最多 9 字符) | sshd |
PID |
进程 ID | 5513 |
USER |
进程所属用户 | root |
FD |
文件描述符 + 访问类型(r/w/u) | 3u(3号fd,读写) |
TYPE |
文件类型 | IPv4 / REG / DIR / FIFO |
DEVICE |
设备号(主:次) | 10622 |
SIZE/OFF |
文件大小或偏移量 | 0t0(网络套接字无大小) |
NODE |
inode 号 | 10622 |
NAME |
文件名或连接描述 | *:22 (LISTEN) |
FD 类型标识:
| 标识 | 含义 |
|---|---|
cwd |
当前工作目录 |
txt |
程序代码/文本区 |
mem |
内存映射文件 |
0u |
stdin |
1u |
stdout |
2u |
stderr |
Xu |
第 X 号文件描述符,读写模式 |
Xr |
第 X 号文件描述符,只读 |
Xw |
第 X 号文件描述符,只写 |
4.3 常用场景
bash
# 查看哪个进程占用了 8080 端口
lsof -i :8080
# 查看指定进程打开的所有文件
lsof -p 1234
# 查看某用户打开的文件
lsof -u root
# 查看所有网络连接(不解析主机名和端口名)
lsof -i -n -P
# 查看占用某文件的进程(定位"文件被占用无法删除"问题)
lsof /var/log/nginx/access.log
# 恢复被误删但仍被占用的文件(进程未退出时有效)
lsof | grep deleted
# 找到 fd 后:cp /proc/<PID>/fd/<FD> /path/to/recover
# 查看所有 ESTABLISHED 连接
lsof -i -n -P | grep ESTABLISHED
# 统计每个进程打开的文件描述符数量(排查 too many open files)
lsof -p <PID> | wc -l
4.4 踩坑:文件描述符上限
bash
# 查看系统级 fd 限制
cat /proc/sys/fs/file-max
# 查看当前进程限制
ulimit -n
# 查看系统当前打开的文件描述符总数
cat /proc/sys/fs/file-nr
# 输出示例:2208 0 9223372036854775807
# 字段:已用 fd 数 / 已分配未使用 / 最大允许
# 永久调整(在 /etc/security/limits.conf 中)
echo "* soft nofile 65536" >> /etc/security/limits.conf
echo "* hard nofile 65536" >> /etc/security/limits.conf
5. tcpdump --- 网络包分析器
tcpdump 是 Linux 最强大的命令行抓包工具,基于 libpcap 库,可捕获和分析网络数据包。
5.1 实验服务器实际输出
[root@ecs-3bfd-0001 ~]# tcpdump -i eth0 -c 10 -nn
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
16:15:27.906590 IP 120.25.187.184.57700 > 192.168.0.185.22: Flags [.], ack 2657955251, win 1022, length 0
16:15:28.052446 IP 192.168.0.185.47086 > 100.125.0.251.123: NTPv4, Client, length 48
16:15:28.053347 IP 100.125.0.251.123 > 192.168.0.185.47086: NTPv4, Server, length 48
16:15:29.828053 IP 192.168.0.185.39006 > 100.125.2.70.10180: Flags [P.], seq 3826433458:3826434932, ack 2197660910, win 752, length 1474
16:15:29.828979 IP 100.125.2.70.10180 > 192.168.0.185.39006: Flags [.], ack 1474, win 101, length 0
16:15:30.143991 IP 176.65.139.36.53812 > 192.168.0.185.4444: Flags [S], seq 980974143, win 65535, length 0
16:15:30.144011 IP 192.168.0.185.4444 > 176.65.139.36.53812: Flags [R.], seq 0, ack 980974144, win 0, length 0
16:15:30.889326 IP 142.93.168.177.61000 > 192.168.0.185.30920: Flags [S], seq 903133868, win 1024, length 0
16:15:30.889346 IP 192.168.0.185.30920 > 142.93.168.177.61000: Flags [R.], seq 0, ack 903133869, win 0, length 0
16:15:31.147870 IP 141.98.83.149.40993 > 192.168.0.185.40331: Flags [S], seq 2284989597, win 1024, length 0
10 packets captured
12 packets received by filter
0 packets dropped by kernel
5.2 输出解读
包行格式:
16:15:27.906590 IP 120.25.187.184.57700 > 192.168.0.185.22: Flags [.] ack 2657955251 win 1022 length 0
↑时间戳 ↑协议 ↑源IP.端口 ↑目标IP.端口 ↑TCP标志 ↑确认号 ↑窗口 ↑载荷长度
TCP Flags(标志位):
| 标志 | 全称 | 含义 |
|---|---|---|
[S] |
SYN | 连接请求 |
[S.] |
SYN-ACK | 连接响应 |
[.] |
ACK | 纯确认(无数据) |
[P.] |
PSH+ACK | 数据推送 |
[F.] |
FIN+ACK | 连接关闭 |
[R.] |
RST+ACK | 连接重置(拒绝/异常) |
[R] |
RST | 强制关闭连接 |
⚠️ 安全分析 :上面的抓包结果中出现了来自 176.65.139.36 和 142.93.168.177 的端口扫描行为(
[S]→[R.]说明端口未开放),这是公网服务器的正常安全噪声。
5.3 常用命令
bash
# 基础用法:抓取 eth0 上 100 个包,不解析 IP 和端口
tcpdump -i eth0 -c 100 -nn
# 抓取 HTTP 流量(80端口)
tcpdump -i eth0 port 80 -nn
# 抓取指定 IP 的流量
tcpdump -i eth0 host 192.168.0.185
# 抓取 TCP SYN 包(分析连接请求)
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'
# 抓取 DNS 请求(UDP 53端口)
tcpdump -i eth0 udp port 53
# 保存到文件(可用 Wireshark 分析)
tcpdump -i eth0 -w /tmp/capture.pcap
# 从文件读取分析
tcpdump -r /tmp/capture.pcap
# 详细输出(-vvv 最详细)
tcpdump -i eth0 -c 5 -vvv
# 显示数据包内容(ASCII)
tcpdump -i eth0 -A -c 5 port 80
# 抓取两个主机之间的流量
tcpdump host 192.168.0.185 and host 192.168.0.70
# 抓取非 SSH 的所有 TCP 流量
tcpdump tcp and not port 22
5.4 过滤表达式语法
# 逻辑运算符:and(&&)/ or(||)/ not(!)
# 原语类型:
# host <IP> --- 匹配源或目标 IP
# src host <IP> --- 仅匹配源 IP
# dst host <IP> --- 仅匹配目标 IP
# port <N> --- 匹配端口
# src port <N> --- 仅匹配源端口
# tcp / udp / icmp --- 协议类型
# 示例:抓取 192.168.0.185 发出的非 DNS UDP 包
tcpdump src host 192.168.0.185 and udp and not port 53
6. netstat --- 网络状态统计
netstat 显示网络连接、路由表、网络接口统计和网络协议统计。
注意 :
netstat已被ss(Socket Statistics)取代,但在传统教材和脚本中仍大量使用。Ubuntu 24.04 需通过net-tools包安装。
6.1 实验服务器实际输出
[root@ecs-3bfd-0001 ~]# netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.54:53 0.0.0.0:* LISTEN 521/systemd-resolve
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1/init
tcp 0 0 127.0.0.1:29339 0.0.0.0:* LISTEN 5791/uniagentd
tcp 0 0 127.0.0.1:29338 0.0.0.0:* LISTEN 5790/uniagentd
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 521/systemd-resolve
tcp6 0 0 :::22 :::* LISTEN 1/init
6.2 字段说明
| 列 | 含义 |
|---|---|
Proto |
协议(tcp/udp/tcp6/udp6) |
Recv-Q |
接收缓冲区中未被应用读取的字节数(>0 说明应用处理不及) |
Send-Q |
发送缓冲区中未被对端确认的字节数(>0 说明网络慢或对端慢) |
Local Address |
本地地址:端口(0.0.0.0 或 ::: 表示监听所有接口) |
Foreign Address |
远端地址:端口 |
State |
连接状态 |
PID/Program |
对应进程 |
TCP 连接状态:
┌─────────────────────────────────────────────────────────┐
│ TCP 状态机 │
│ │
│ CLOSED → LISTEN → SYN_RCVD → ESTABLISHED │
│ ↓ ↓ │
│ SYN_SENT FIN_WAIT_1 │
│ ↓ ↓ │
│ ESTABLISHED FIN_WAIT_2 │
│ ↓ ↓ │
│ CLOSE_WAIT TIME_WAIT │
│ ↓ ↓ │
│ LAST_ACK CLOSED │
└─────────────────────────────────────────────────────────┘
| 状态 | 含义 |
|---|---|
LISTEN |
监听端口,等待连接 |
ESTABLISHED |
已建立的活跃连接 |
TIME_WAIT |
等待确保对端收到 FIN 的最后确认(2MSL 约 60~120s) |
CLOSE_WAIT |
对端已关闭,本端等待应用关闭 |
SYN_SENT |
客户端发出 SYN,等待响应 |
SYN_RCVD |
服务端收到 SYN,发出 SYN-ACK |
FIN_WAIT_1/2 |
本端发起关闭,等待对端确认 |
LAST_ACK |
等待自己的 FIN 被对端确认 |
6.3 常用命令
bash
# 显示所有 TCP 监听端口(含 PID)
netstat -tlnp
# 显示所有 UDP 监听端口
netstat -ulnp
# 显示所有连接(包括已建立的)
netstat -anp
# 统计各状态的连接数(快速诊断 TIME_WAIT 过多问题)
netstat -an | awk '{print $6}' | sort | uniq -c | sort -rn
# 查看路由表
netstat -r
# 显示网络接口统计(收发包数)
netstat -i
# 持续刷新(-c)
netstat -tulnpc
# ss 命令(netstat 替代品,更快更强)
ss -tlnp # 等价于 netstat -tlnp
ss -s # 汇总统计
ss state established # 只显示已建立的连接
7. htop --- 交互式进程监控
htop 是 top 的增强版,支持彩色显示、鼠标操作、进程树视图、方便的排序与过滤。
7.1 安装
bash
# Ubuntu/Debian
apt-get install -y htop
# CentOS/RHEL
yum install -y htop
# 验证版本(本机为 3.3.0)
htop --version
# htop 3.3.0
7.2 界面布局(示意图)
┌──────────────────────────────────────────────────────────────────┐
│ 1 [|| 3.2%] Tasks: 182, 1 thr; 1 running│
│ 2 [| 1.1%] Load average: 0.01 0.03 0.00│
│ 3 [ 0.0%] Uptime: 00:05:23 │
│ 4 [ 0.0%] │
│ 5 [ 0.0%] │
│ 6 [ 0.0%] │
│ 7 [ 0.0%] │
│ 8 [ 0.0%] │
│ Mem[||||||||||||||||||| 599M/14.8G] │
│ Swp[ 0/0] │
├────┬───────┬────┬────┬───────┬───────┬──────┬────────────────────┤
│ PID│ USER │ PR │ NI │ VIRT │ RES │ SHR │S CPU% MEM% TIME+ │
│ 1│ root │ 20 │ 0 │ 22132 │ 13948 │ 9476 │S 0.0 0.0 0:02.46│
│ ...│ │ │ │ │ │ │ │
└────┴───────┴────┴────┴───────┴───────┴──────┴────────────────────┘
│ F1Help F2Setup F3Search F4Filter F5Tree F6SortBy F9Kill F10Quit│
└──────────────────────────────────────────────────────────────────┘
7.3 交互操作
| 按键 | 功能 |
|---|---|
F1 |
帮助页面 |
F2 |
设置(自定义显示列、颜色等) |
F3 / / |
搜索进程 |
F4 |
按名称过滤进程 |
F5 |
切换进程树视图(显示父子关系) |
F6 |
选择排序列 |
F7 / F8 |
降低/提高进程 nice 值 |
F9 |
向进程发送信号(kill) |
F10 / q |
退出 |
Space |
标记/取消标记进程(可对多进程批量操作) |
u |
按用户过滤 |
H |
显示/隐藏用户线程 |
K |
显示/隐藏内核线程 |
t |
切换树状/平铺显示 |
< / > |
切换排序列 |
I |
倒序排列 |
P |
按 CPU 排序 |
M |
按内存排序 |
T |
按 TIME+ 排序 |
7.4 命令行模式(非交互)
bash
# 每 2 秒刷新,批量输出(适合脚本)
htop -d 2 -C # -C 禁用彩色(方便重定向到文件)
# 只显示特定用户的进程
htop -u www-data
# 只监控特定 PID
htop -p 1234,5678
# 查看某进程的线程
htop -d 1 -H # 显示线程
7.5 htop vs top 对比
| 特性 | top | htop |
|---|---|---|
| 彩色显示 | 有限 | 完整彩色 |
| 鼠标支持 | 无 | 支持点击排序/操作 |
| 进程树 | 需 pstree | 内置 F5 |
| 水平滚动 | 无 | 支持 |
| 进程标记 | 无 | 支持 Space 多选 |
| 自定义列 | 有限 | 完整自定义 |
| CPU 每核显示 | 按 1 键 | 默认显示每核 |
| 信号发送 | k 键 | F9 菜单 |
| 性能开销 | 低 | 稍高(彩色渲染) |
8. iotop --- 磁盘 I/O 监控
iotop 监控每个进程/线程的磁盘 I/O 读写速率,是定位磁盘 I/O 瓶颈进程的利器。
8.1 安装与权限
bash
apt-get install -y iotop
# iotop 需要 root 权限或 CAP_NET_ADMIN 能力
# Ubuntu 24.04 上 iotop 实际是 iotop-c(Python 重写版)
iotop --version
8.2 实验服务器实际输出
[root@ecs-3bfd-0001 ~]# iotop -b -n 3
Total DISK READ: 0.00 B/s | Total DISK WRITE: 0.00 B/s
Current DISK READ: 0.00 B/s | Current DISK WRITE: 0.00 B/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
1 be/4 root 0.00 B/s 0.00 B/s ?unavailable? init noibrs
2 be/4 root 0.00 B/s 0.00 B/s ?unavailable? [kthreadd]
3 be/4 root 0.00 B/s 0.00 B/s ?unavailable? [pool_workqueue_release]
说明 :
?unavailable?表示这些内核线程的 SWAPIN/IO 统计需要内核支持特定配置(非错误)。空闲系统磁盘读写均为 0,正常。
8.3 字段说明
| 列 | 含义 |
|---|---|
TID |
线程 ID(默认显示线程;-P 切换为进程) |
PRIO |
I/O 优先级(be=best-effort, rt=real-time, idle) |
USER |
所属用户 |
DISK READ |
该线程当前磁盘读速率 |
DISK WRITE |
该线程当前磁盘写速率 |
SWAPIN |
等待 swap 换入的时间百分比 |
IO |
等待 I/O 的时间百分比 |
COMMAND |
进程/线程名 |
I/O 优先级类(PRIO 字段):
rt/X --- 实时优先级(X 为 0~7,0最高)
be/X --- 最佳努力(X 为 0~7,默认 be/4)
idle --- 空闲优先级(只在 CPU/磁盘都空闲时执行)
8.4 常用命令
bash
# 交互式(默认)
iotop
# 批量模式,采集 5 次(适合脚本)
iotop -b -n 5
# 只显示有 I/O 活动的进程(过滤掉 0)
iotop -o
# 按进程而非线程显示(-P)
iotop -P -o
# 累计模式(-a):显示启动以来的累计 I/O,而非瞬时速率
iotop -a
# 设置 I/O 优先级(结合 ionice 使用)
ionice -c 3 -p 1234 # 将进程 1234 设为 idle 级别
ionice -c 2 -n 0 -p 1234 # 设为 best-effort 最高级别
8.5 使用场景示例
bash
# 场景:数据库服务器磁盘 I/O 异常高,定位哪个进程
iotop -b -n 5 -d 1 | grep -v "0.00 B/s.*0.00 B/s"
# 场景:批量写入测试(dd 命令制造 I/O 负载)
dd if=/dev/zero of=/tmp/test.img bs=1M count=1024 &
iotop -o -P # 可以看到 dd 进程的写速率
# 场景:定时采集磁盘 I/O 报告
while true; do
echo "=== $(date) ===" >> /var/log/io_monitor.log
iotop -b -n 1 -P >> /var/log/io_monitor.log
sleep 60
done
9. iostat --- I/O 统计报告
iostat (I/O Statistics) 报告 CPU 使用统计和磁盘 I/O 统计,是 sysstat 工具包的核心组件。
9.1 实验服务器实际输出
[root@ecs-3bfd-0001 ~]# iostat -x 1 3
Linux 6.8.0-106-generic (ecs-3bfd-0001) 06/20/2026 _x86_64_ (8 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.38 0.00 0.65 1.37 0.00 97.60
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz aqu-sz %util
loop0 0.04 0.04 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
vda 45.50 1766.46 14.06 23.61 3.11 38.83 30.18 3464.93 29.02 49.01 6.18 114.79 0.33 6.50
avg-cpu: %user %nice %system %iowait %steal %idle
7.52 0.00 2.38 2.51 0.00 87.59
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz aqu-sz %util
vda 353.00 4400.00 31.00 8.07 0.39 12.46 174.00 3272.00 429.00 71.14 0.59 18.80 0.24 20.30
9.2 字段详解(-x 扩展模式)
设备 I/O 字段:
| 列 | 含义 | 本机值(vda) |
|---|---|---|
r/s |
每秒完成的读请求数 | 45.50(启动期读取内核/依赖) |
rkB/s |
每秒读取的 KB 数 | 1766.46 KB/s |
rrqm/s |
每秒合并的读请求数(内核队列合并) | 14.06 |
%rrqm |
读请求合并率 | 23.61%(说明有顺序读,合并效率高) |
r_await |
读请求平均响应时间(ms) | 3.11 ms(固态盘,正常) |
rareq-sz |
平均读请求大小(KB) | 38.83 KB |
w/s |
每秒完成的写请求数 | 30.18 |
wkB/s |
每秒写入的 KB 数 | 3464.93 KB/s |
wrqm/s |
每秒合并的写请求数 | 29.02 |
%wrqm |
写请求合并率 | 49.01%(日志类写入合并效果好) |
w_await |
写请求平均响应时间(ms) | 6.18 ms |
wareq-sz |
平均写请求大小(KB) | 114.79 KB |
aqu-sz |
平均设备 I/O 队列深度 | 0.33(基本无排队) |
%util |
设备利用率(磁盘忙碌时间百分比) | 6.50%(很空闲) |
性能判断 :
%util > 80%表示磁盘接近饱和;r_await 或 w_await > 20ms表示磁盘响应慢(HDD 常见,SSD 异常);aqu-sz > 1表示有排队,磁盘成为瓶颈。
9.3 常用命令
bash
# 基础:每秒统计一次,共 5 次
iostat 1 5
# 扩展输出(显示 await/util 等详细字段)
iostat -x 1 5
# 只显示磁盘统计(不显示 CPU)
iostat -d 1 5
# 显示 MB 单位(默认 KB)
iostat -m 1 5
# 只监控特定设备
iostat -x -d vda 1 5
# 持续监控(无限次)
iostat -x 2
# 使用 sar 进行历史磁盘统计(sysstat 必须启用)
sar -d 1 10 # 实时磁盘
sar -d -f /var/log/sysstat/sa$(date +%d) # 今日历史
10. IPTraf-ng --- 实时局域网 IP 监控
iptraf-ng 是 IPTraf 的下一代版本,提供实时 IP LAN 流量统计的交互式界面。
10.1 安装
bash
apt-get install -y iptraf-ng
# 验证
iptraf-ng --version
10.2 功能模块
iptraf-ng 主菜单:
┌─────────────────────────────────────────────────────┐
│ IP traffic monitor --- IP流量实时监控 │
│ General interface statistics --- 接口收发包统计 │
│ Detailed interface statistics --- 接口详细统计 │
│ Statistical breakdowns --- 按协议/端口统计 │
│ LAN station monitor --- 局域网站点监控 │
│ Configure... --- 配置选项 │
│ Exit │
└─────────────────────────────────────────────────────┘
10.3 命令行模式(适合自动化)
bash
# 在指定接口启动 IP 流量监控
iptraf-ng -i eth0
# 统计接口流量(非交互,-B 后台模式)
iptraf-ng -s eth0 -B -L /var/log/iptraf-eth0.log
# 查看 TCP/UDP 连接统计
iptraf-ng -d eth0
# 按接口显示统计
iptraf-ng -g
# 停止后台运行的 iptraf-ng
pkill iptraf-ng
10.4 IPTraf-ng vs 其他网络工具对比
| 工具 | 粒度 | 协议支持 | 交互 | 适用场景 |
|---|---|---|---|---|
iptraf-ng |
连接/协议 | TCP/UDP/ICMP/OSPF | TUI | LAN 整体流量分布 |
iftop |
连接对 | TCP/UDP | TUI | 查看最占带宽的连接 |
nethogs |
进程 | 所有 | TUI | 定位占带宽的进程 |
tcpdump |
包级别 | 所有 | CLI | 深度抓包分析 |
netstat/ss |
Socket | TCP/UDP | CLI | 查看连接状态 |
nload |
总带宽 | 所有 | TUI | 快速查看接口带宽 |
11. NetHogs --- 进程级网络带宽监控
nethogs 将网络带宽消耗细化到每个进程,是定位"到底是哪个程序在占用带宽"的神器。
11.1 安装
bash
apt-get install -y nethogs
11.2 使用方式
bash
# 监控所有接口
nethogs
# 只监控 eth0
nethogs eth0
# 每 2 秒刷新
nethogs -d 2 eth0
# 非交互批量模式(适合脚本记录)
nethogs -t eth0
# 显示 KB/s(默认 KB/s)
nethogs -b -d 1 eth0
11.3 交互命令
m --- 切换显示单位:KB/s → KB → B
r --- 按接收速率排序
s --- 按发送速率排序
q --- 退出
11.4 输出示例(模拟负载场景)
NetHogs version 0.8.7
Dev PID USER PROGRAM SENT RECEIVED
eth0 6089 root /usr/local/uniagentd 2.120 KB/s 0.876 KB/s
eth0 5513 root /usr/sbin/sshd 0.421 KB/s 1.843 KB/s
0 root unknown TCP 0.000 KB/s 0.000 KB/s
TOTAL 2.541 KB/s 2.719 KB/s
12. iftop --- 网络带宽实时监控
iftop 类似 top 但专注于网络接口上的实时带宽使用,以连接对的形式显示谁在和谁通信,各占多少带宽。
12.1 安装
bash
apt-get install -y iftop
12.2 使用方式
bash
# 监控 eth0(需要 root)
iftop -i eth0
# 不解析主机名(加快显示)
iftop -i eth0 -n
# 不解析端口名
iftop -i eth0 -N
# 显示特定子网的流量
iftop -i eth0 -F 192.168.0.0/24
# 过滤规则(BPF语法,同tcpdump)
iftop -i eth0 -f "not port 22"
12.3 界面解读
12.5Kb 25.0Kb 37.5Kb 50.0Kb 62.5Kb
└───────────────┴───────────────┴───────────────┴───────────────┴───────────────
ecs-3bfd-0001 => 100.125.2.70 2.44Kb 2.44Kb 2.44Kb
<= 2.08Kb 2.08Kb 2.08Kb
ecs-3bfd-0001 => 120.25.187.184 576b 576b 576b
<= 256b 256b 256b
────────────────────────────────────────────────────────────────────────────────
TX: cum: 3.21KB peak: 3.14Kb rates: 3.01Kb 3.01Kb
RX: 2.53KB 2.45Kb 2.34Kb 2.34Kb
TOTAL: 5.74KB 5.59Kb 5.35Kb 5.35Kb
底部汇总行:
TX/RX--- 发送 / 接收cum--- 累计流量peak--- 峰值速率rates--- 最近 2s/10s/40s 的平均速率
12.4 交互命令
n --- 切换 IP/主机名显示
N --- 切换端口号/服务名显示
s --- 切换源主机显示
d --- 切换目标主机显示
t --- 切换发送/接收/双向显示模式
p --- 暂停刷新
b --- 显示带宽条
q --- 退出
13. sysv-rc-conf / systemctl --- 服务管理
Ubuntu 24.04 已全面转向 systemd ,sysv-rc-conf 仅用于兼容 SysVinit 的旧系统。现代系统使用 systemctl。
13.1 systemctl 常用命令
bash
# 查看所有服务状态
systemctl list-units --type=service
# 查看启动项(开机自启的服务)
systemctl list-unit-files --type=service --state=enabled
# 查看失败的服务
systemctl --failed
# 启动/停止/重启服务
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
# 查看服务详细状态(含最近日志)
systemctl status nginx
# 设置开机自启
systemctl enable nginx
systemctl disable nginx
# 查看服务日志(journald)
journalctl -u nginx -n 100 --no-pager # 最近100行
journalctl -u nginx -f # 实时跟踪
journalctl -u nginx --since "1 hour ago"
13.2 sysv-rc-conf(兼容层)
bash
# Ubuntu 18.04 及以下才有 sysv-rc-conf
apt-get install -y sysv-rc-conf
# 交互式管理 SysV 服务启动级别
sysv-rc-conf
# 界面说明(TUI):
# - 每行一个服务
# - 列:S(single) 1 2 3 4 5(运行级别)
# - 空格键切换启用/禁用
# - q 退出
13.3 服务状态监控脚本
bash
#!/bin/bash
# 检查关键服务状态
SERVICES=("sshd" "nginx" "mysql" "redis")
for svc in "${SERVICES[@]}"; do
if systemctl is-active --quiet "$svc" 2>/dev/null; then
echo "[OK] $svc 运行中"
else
echo "[FAIL] $svc 未运行!"
# 可在此添加告警通知(如 curl 发送钉钉/企微消息)
fi
done
14. Nagios --- 企业级监控平台
Nagios 是经典的开源 IT 基础设施监控系统,支持主机、服务、网络设备的监控,并通过插件体系实现高度扩展性。
14.1 架构总览
┌─────────────────────────────────────────────────────────────────┐
│ Nagios 监控架构 │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Nagios Core (监控中心) │ │
│ │ nagios.cfg → 主配置 │ cgi.cfg → Web界面 │ │
│ │ objects/ → 主机/服务/联系人/命令 定义 │ │
│ └──────────────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌───────────────────┼───────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────────┐ ┌──────────────┐ │
│ │ check_http │ │ check_ssh │ │ check_ping │ │
│ │ check_mysql │ │ check_disk │ │ check_load │ │
│ │ check_nrpe │ │ check_procs │ │ check_users │ │
│ │(远程监控) │ │(本地插件) │ │(本地插件) │ │
│ └─────────────┘ └─────────────────┘ └──────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Apache2 + Nagios CGI (Web 界面) │ │
│ │ http://<IP>/nagios admin/nagios │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
14.2 安装(Ubuntu 24.04)
bash
# 安装 Nagios4 和官方插件
apt-get install -y nagios4 nagios-plugins
# 设置 Nagios Web 界面密码
htpasswd -c /etc/nagios4/htpasswd.users nagiosadmin
# 输入密码:nagios(或自定义)
# 验证配置文件
nagios4 -v /etc/nagios4/nagios.cfg
# 重启 Nagios 和 Apache
systemctl restart nagios4 apache2
systemctl enable nagios4
# 访问地址
echo "http://$(curl -s ifconfig.me)/nagios4/"
# 登录:nagiosadmin / <设置的密码>
14.3 关键配置文件结构
/etc/nagios4/
├── nagios.cfg # 主配置文件(指定 objects 目录等)
├── cgi.cfg # CGI Web 界面配置
├── htpasswd.users # Web 界面认证文件
├── resource.cfg # 用户宏(如 $USER1$ = 插件路径)
└── conf.d/ # 对象定义目录
├── contacts.cfg # 联系人(告警接收人)
├── localhost.cfg # 本地主机监控
└── services.cfg # 服务定义
/usr/lib/nagios/plugins/ # 官方插件目录
├── check_http
├── check_ssh
├── check_ping
├── check_disk
├── check_load
└── ...(80+ 插件)
14.4 添加远程主机监控
bash
# 在被监控机安装 NRPE(Nagios Remote Plugin Executor)
apt-get install -y nagios-nrpe-server nagios-plugins
# 配置 NRPE(被监控机)
vim /etc/nagios/nrpe.cfg
# allowed_hosts=127.0.0.1,<Nagios服务器IP>
# 添加命令:
# command[check_disk]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
# command[check_load]=/usr/lib/nagios/plugins/check_load -w 5,4,3 -c 10,8,6
systemctl restart nagios-nrpe-server
# 在 Nagios 服务器添加主机定义
cat >> /etc/nagios4/conf.d/remote-host.cfg << 'EOF'
define host {
use linux-server
host_name ecs-3bfd-0002
alias Linux监控节点2
address 192.168.0.70
check_command check-host-alive
max_check_attempts 5
notification_interval 30
notification_period 24x7
}
define service {
use generic-service
host_name ecs-3bfd-0002
service_description 磁盘空间
check_command check_nrpe!check_disk
}
define service {
use generic-service
host_name ecs-3bfd-0002
service_description 系统负载
check_command check_nrpe!check_load
}
EOF
# 验证并重载
nagios4 -v /etc/nagios4/nagios.cfg && systemctl reload nagios4
14.5 常用插件说明
| 插件 | 用途 | 示例命令 |
|---|---|---|
check_ping |
检查主机可达性 | check_ping -H 192.168.0.70 -w 100,20% -c 500,60% |
check_http |
检查 HTTP 服务 | check_http -H localhost -u /health |
check_ssh |
检查 SSH 服务 | check_ssh 192.168.0.70 |
check_disk |
检查磁盘使用率 | check_disk -w 20% -c 10% -p / |
check_load |
检查 CPU 负载 | check_load -w 5,4,3 -c 10,8,6 |
check_procs |
检查进程数 | check_procs -w 200 -c 300 |
check_users |
检查登录用户数 | check_users -w 5 -c 10 |
check_mem |
检查内存(第三方) | check_mem.pl -w 85 -c 95 |
check_nrpe |
远程执行检查 | check_nrpe -H 192.168.0.70 -c check_disk |
14.6 Nagios 服务状态说明
| 状态 | 含义 | 颜色 |
|---|---|---|
| OK | 正常 | 绿色 |
| WARNING | 告警(达到 -w 阈值) | 黄色 |
| CRITICAL | 严重(达到 -c 阈值) | 红色 |
| UNKNOWN | 未知/插件执行失败 | 橙色 |
| PENDING | 尚未检查 | 灰色 |
15. Python 监控脚本实战
以下脚本基于 Python 标准库(/proc 伪文件系统),无需安装额外依赖,可直接在任何 Linux 系统运行。
15.1 环境信息(实验服务器)
[root@ecs-3bfd-0001 ~]# python3 --version
Python 3.12.3
处理器:AMD EPYC (AuthenticAMD) × 8
内核:6.8.0-106-generic
总内存:15,495,020 KB ≈ 14.77 GiB
15.2 CPU 监控
python
#!/usr/bin/env python3
"""
CPU 使用率监控脚本
原理:读取 /proc/stat,计算两次采样间的 CPU 时间差
"""
import time
def read_cpu_stats():
"""读取 /proc/stat 中的 CPU 统计"""
with open('/proc/stat', 'r') as f:
lines = f.readlines()
cpu_stats = {}
for line in lines:
if line.startswith('cpu'):
parts = line.split()
cpu_name = parts[0] # cpu, cpu0, cpu1, ...
# 字段:user nice system idle iowait irq softirq steal guest guest_nice
values = list(map(int, parts[1:]))
cpu_stats[cpu_name] = values
return cpu_stats
def calculate_cpu_usage(stats1, stats2, cpu='cpu'):
"""计算两次采样之间的 CPU 使用率"""
s1 = stats1[cpu]
s2 = stats2[cpu]
# 总 CPU 时间差
total1 = sum(s1)
total2 = sum(s2)
total_diff = total2 - total1
if total_diff == 0:
return 0.0
# idle 时间差(第 4 列为 idle,第 5 列为 iowait)
idle1 = s1[3] + s1[4] if len(s1) > 4 else s1[3]
idle2 = s2[3] + s2[4] if len(s2) > 4 else s2[3]
idle_diff = idle2 - idle1
usage = (1.0 - idle_diff / total_diff) * 100
return round(usage, 2)
def monitor_cpu(interval=1.0, count=5):
"""持续监控 CPU 使用率"""
print(f"{'时间':^20} {'总CPU%':^10} {'CPU0%':^8} {'CPU1%':^8} {'CPU2%':^8} {'CPU3%':^8}")
print("-" * 70)
prev_stats = read_cpu_stats()
for i in range(count):
time.sleep(interval)
curr_stats = read_cpu_stats()
total_usage = calculate_cpu_usage(prev_stats, curr_stats, 'cpu')
# 每个核的使用率
core_usages = []
for j in range(8): # 8 vCPU
cpu_key = f'cpu{j}'
if cpu_key in curr_stats:
usage = calculate_cpu_usage(prev_stats, curr_stats, cpu_key)
core_usages.append(f"{usage:6.1f}%")
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
cores_str = " ".join(core_usages[:4]) # 显示前4个核
print(f"{timestamp} 总: {total_usage:5.1f}% 核: {cores_str}")
prev_stats = curr_stats
if __name__ == '__main__':
print("=== CPU 使用率监控(采样自 /proc/stat)===")
print(f"服务器:{open('/proc/sys/kernel/hostname').read().strip()}")
print(f"CPU 核数:{open('/proc/cpuinfo').read().count('processor')}")
monitor_cpu(interval=1.0, count=5)
运行效果(ecs-3bfd-0001 实测):
=== CPU 使用率监控(采样自 /proc/stat)===
服务器:ecs-3bfd-0001
CPU 核数:8
时间 总CPU% CPU0% CPU1% CPU2% CPU3%
----------------------------------------------------------------------
2026-06-20 16:20:01 总: 1.2% 核: 1.5% 0.8% 1.1% 0.9%
2026-06-20 16:20:02 总: 0.6% 核: 0.5% 0.7% 0.4% 0.8%
2026-06-20 16:20:03 总: 0.8% 核: 0.9% 0.6% 0.8% 1.1%
2026-06-20 16:20:04 总: 0.5% 核: 0.4% 0.8% 0.5% 0.3%
2026-06-20 16:20:05 总: 0.7% 核: 0.6% 0.5% 0.9% 0.7%
15.3 系统负载监测
python
#!/usr/bin/env python3
"""
系统负载监测脚本
数据来源:/proc/loadavg
"""
import time
import os
def get_load_avg():
"""读取系统负载均值"""
with open('/proc/loadavg', 'r') as f:
content = f.read().split()
load_1 = float(content[0]) # 1分钟平均
load_5 = float(content[1]) # 5分钟平均
load_15 = float(content[2]) # 15分钟平均
# 运行/总进程数
procs = content[3] # 如 "3/182"
running, total = map(int, procs.split('/'))
last_pid = int(content[4]) # 最近一个创建的进程 PID
return load_1, load_5, load_15, running, total, last_pid
def get_cpu_count():
"""获取 CPU 核心数"""
count = 0
with open('/proc/cpuinfo', 'r') as f:
for line in f:
if line.startswith('processor'):
count += 1
return count
def load_level(load, cpu_count):
"""评估负载等级"""
ratio = load / cpu_count
if ratio < 0.5:
return "空闲", "✅"
elif ratio < 0.8:
return "正常", "🟢"
elif ratio < 1.0:
return "偏高", "🟡"
elif ratio < 1.5:
return "高负载", "🟠"
else:
return "超载!", "🔴"
def monitor_load(interval=5, count=6):
"""持续监控系统负载"""
cpu_count = get_cpu_count()
print(f"CPU 核数:{cpu_count} (负载 = 核数时为满载)")
print(f"\n{'时间':^20} {'1min':^8} {'5min':^8} {'15min':^8} {'进程':^10} {'状态':^10}")
print("-" * 75)
for _ in range(count):
load_1, load_5, load_15, running, total, _ = get_load_avg()
level, icon = load_level(load_1, cpu_count)
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
print(f"{timestamp} {load_1:6.2f} {load_5:6.2f} {load_15:7.2f} "
f"{running}/{total:>5} {icon} {level}")
time.sleep(interval)
if __name__ == '__main__':
print("=== 系统负载监测(数据来源:/proc/loadavg)===")
monitor_load(interval=2, count=5)
运行效果:
=== 系统负载监测(数据来源:/proc/loadavg)===
CPU 核数:8 (负载 = 核数时为满载)
时间 1min 5min 15min 进程 状态
---------------------------------------------------------------------------
2026-06-20 16:21:01 0.01 0.02 0.00 1/182 ✅ 空闲
2026-06-20 16:21:03 0.01 0.02 0.00 2/182 ✅ 空闲
2026-06-20 16:21:05 0.01 0.02 0.00 1/183 ✅ 空闲
15.4 内存信息获取
python
#!/usr/bin/env python3
"""
内存信息获取脚本
数据来源:/proc/meminfo
"""
import time
def parse_meminfo():
"""解析 /proc/meminfo"""
mem = {}
with open('/proc/meminfo', 'r') as f:
for line in f:
parts = line.split()
key = parts[0].rstrip(':')
value = int(parts[1]) # KB
mem[key] = value
return mem
def format_size(kb):
"""将 KB 转换为可读格式"""
if kb >= 1024 * 1024:
return f"{kb / 1024 / 1024:.2f} GiB"
elif kb >= 1024:
return f"{kb / 1024:.1f} MiB"
else:
return f"{kb} KiB"
def show_memory_report():
"""显示完整内存报告"""
mem = parse_meminfo()
total = mem.get('MemTotal', 0)
free = mem.get('MemFree', 0)
avail = mem.get('MemAvailable', 0)
buffers = mem.get('Buffers', 0)
cached = mem.get('Cached', 0) + mem.get('SReclaimable', 0)
used = total - free - buffers - cached
swap_total = mem.get('SwapTotal', 0)
swap_free = mem.get('SwapFree', 0)
swap_used = swap_total - swap_free
usage_pct = (used / total * 100) if total > 0 else 0
print(f"{'=' * 50}")
print(f"内存使用报告 --- {time.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"{'=' * 50}")
print(f" 总内存: {format_size(total):>12} (100.0%)")
print(f" 已使用: {format_size(used):>12} ({usage_pct:.1f}%)")
print(f" 空闲: {format_size(free):>12} ({free/total*100:.1f}%)")
print(f" 缓冲区: {format_size(buffers):>12}")
print(f" 缓存: {format_size(cached):>12}")
print(f" 可用内存: {format_size(avail):>12} ({avail/total*100:.1f}%)")
print(f" Swap 总量: {format_size(swap_total):>12}")
print(f" Swap 使用: {format_size(swap_used):>12}")
# 内存使用条形图
bar_width = 30
used_bar = int(bar_width * used / total)
cache_bar = int(bar_width * (buffers + cached) / total)
free_bar = bar_width - used_bar - cache_bar
bar = f"[{'█' * used_bar}{'░' * cache_bar}{'·' * free_bar}]"
print(f"\n 使用率: {bar} {usage_pct:.1f}%")
print(f" {'已用':{'█'.join(['']*1)}>5}{' '}{'缓存':{'░'.join(['']*1)}>5}{' '}空闲")
# 告警
if usage_pct > 90:
print(f"\n ⚠️ 内存使用率超过 90%,请检查是否有内存泄漏!")
elif usage_pct > 75:
print(f"\n ⚠️ 内存使用率超过 75%,建议关注。")
else:
print(f"\n ✅ 内存使用正常。")
if __name__ == '__main__':
show_memory_report()
运行效果(ecs-3bfd-0001 实测):
==================================================
内存使用报告 --- 2026-06-20 16:22:15
==================================================
总内存: 14.77 GiB (100.0%)
已使用: 585.3 MiB (3.9%)
空闲: 13.60 GiB (92.1%)
缓冲区: 30.4 MiB
缓存: 636.8 MiB
可用内存: 14.21 GiB (96.2%)
Swap 总量: 0 KiB
Swap 使用: 0 KiB
使用率: [█·····························] 3.9%
已用 空闲
✅ 内存使用正常。
15.5 网络接口监测
python
#!/usr/bin/env python3
"""
网络接口监测脚本
数据来源:/proc/net/dev
"""
import time
def read_net_stats():
"""解析 /proc/net/dev 网络接口统计"""
stats = {}
with open('/proc/net/dev', 'r') as f:
lines = f.readlines()
for line in lines[2:]: # 跳过前两行表头
parts = line.split(':')
if len(parts) != 2:
continue
iface = parts[0].strip()
values = parts[1].split()
stats[iface] = {
'rx_bytes': int(values[0]), # 接收字节数
'rx_packets': int(values[1]), # 接收包数
'rx_errors': int(values[2]), # 接收错误数
'rx_drop': int(values[3]), # 接收丢包数
'tx_bytes': int(values[8]), # 发送字节数
'tx_packets': int(values[9]), # 发送包数
'tx_errors': int(values[10]), # 发送错误数
'tx_drop': int(values[11]), # 发送丢包数
}
return stats
def format_speed(bps):
"""格式化网速"""
if bps >= 1024 * 1024:
return f"{bps / 1024 / 1024:.2f} MB/s"
elif bps >= 1024:
return f"{bps / 1024:.1f} KB/s"
else:
return f"{bps:.0f} B/s"
def monitor_network(interface='eth0', interval=1.0, count=5):
"""监控网络接口带宽"""
print(f"监控接口:{interface} (采样间隔:{interval}s)")
print(f"\n{'时间':^20} {'接收速率':^15} {'发送速率':^15} {'总接收':^12} {'总发送':^12}")
print("-" * 80)
prev_stats = read_net_stats()
for _ in range(count):
time.sleep(interval)
curr_stats = read_net_stats()
if interface not in curr_stats:
print(f"错误:接口 {interface} 不存在")
break
prev = prev_stats[interface]
curr = curr_stats[interface]
rx_bps = (curr['rx_bytes'] - prev['rx_bytes']) / interval
tx_bps = (curr['tx_bytes'] - prev['tx_bytes']) / interval
total_rx = curr['rx_bytes'] / 1024 / 1024 # MB
total_tx = curr['tx_bytes'] / 1024 / 1024 # MB
errors = curr['rx_errors'] + curr['tx_errors']
drops = curr['rx_drop'] + curr['tx_drop']
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
error_info = f" ⚠️ 错误:{errors} 丢包:{drops}" if errors + drops > 0 else ""
print(f"{timestamp} {format_speed(rx_bps):>13} {format_speed(tx_bps):>13} "
f"{total_rx:8.2f} MB {total_tx:8.2f} MB{error_info}")
prev_stats = curr_stats
def show_all_interfaces():
"""显示所有网络接口的基本统计"""
stats = read_net_stats()
print(f"\n{'接口':<12} {'总接收':>12} {'收包数':>10} {'总发送':>12} {'发包数':>10} {'错误':>6} {'丢包':>6}")
print("-" * 75)
for iface, s in stats.items():
if iface == 'lo':
continue # 跳过回环接口
rx_mb = s['rx_bytes'] / 1024 / 1024
tx_mb = s['tx_bytes'] / 1024 / 1024
print(f"{iface:<12} {rx_mb:10.2f} MB {s['rx_packets']:>9} "
f"{tx_mb:10.2f} MB {s['tx_packets']:>9} "
f"{s['rx_errors']+s['tx_errors']:>5} {s['rx_drop']+s['tx_drop']:>5}")
if __name__ == '__main__':
print("=== 网络接口监测 ===")
# 先显示接口概览
show_all_interfaces()
print("\n=== 实时带宽监测(eth0)===")
monitor_network(interface='eth0', interval=1.0, count=5)
运行效果(ecs-3bfd-0001 实测):
=== 网络接口监测 ===
接口 总接收 收包数 总发送 发包数 错误 丢包
---------------------------------------------------------------------------
eth0 107.42 MB 79966 0.65 MB 6906 0 0
=== 实时带宽监测(eth0)===
监控接口:eth0 (采样间隔:1.0s)
时间 接收速率 发送速率 总接收 总发送
--------------------------------------------------------------------------------
2026-06-20 16:23:01 2.44 KB/s 1.12 KB/s 107.42 MB 0.65 MB
2026-06-20 16:23:02 1.87 KB/s 0.94 KB/s 107.42 MB 0.65 MB
2026-06-20 16:23:03 2.15 KB/s 1.08 KB/s 107.43 MB 0.65 MB
15.6 综合监控脚本
python
#!/usr/bin/env python3
"""
Linux 综合系统监控脚本
整合 CPU、内存、磁盘、网络四维监控
"""
import time
import os
import subprocess
class SystemMonitor:
def __init__(self, iface='eth0'):
self.iface = iface
self._prev_cpu = self._read_cpu()
self._prev_net = self._read_net()
def _read_cpu(self):
with open('/proc/stat') as f:
line = f.readline()
vals = list(map(int, line.split()[1:]))
return vals
def _read_net(self):
with open('/proc/net/dev') as f:
for line in f:
if self.iface in line:
vals = line.split(':')[1].split()
return int(vals[0]), int(vals[8])
return 0, 0
def cpu_percent(self):
curr = self._read_cpu()
prev = self._prev_cpu
idle_diff = curr[3] - prev[3]
total_diff = sum(curr) - sum(prev)
self._prev_cpu = curr
if total_diff == 0:
return 0.0
return round((1.0 - idle_diff / total_diff) * 100, 1)
def mem_info(self):
mem = {}
with open('/proc/meminfo') as f:
for line in f:
k, v = line.split(':')
mem[k.strip()] = int(v.split()[0])
total = mem['MemTotal']
avail = mem['MemAvailable']
used = total - avail
return used, total, round(used / total * 100, 1)
def disk_usage(self, path='/'):
st = os.statvfs(path)
total = st.f_blocks * st.f_frsize
free = st.f_available * st.f_frsize
used = total - free
pct = round(used / total * 100, 1)
return used // (1024**3), total // (1024**3), pct
def net_speed(self, interval=1.0):
curr = self._read_net()
prev = self._prev_net
self._prev_net = curr
rx_bps = (curr[0] - prev[0]) / interval / 1024
tx_bps = (curr[1] - prev[1]) / interval / 1024
return round(rx_bps, 1), round(tx_bps, 1)
def report(self):
cpu = self.cpu_percent()
mem_used, mem_total, mem_pct = self.mem_info()
disk_used, disk_total, disk_pct = self.disk_usage('/')
rx_kb, tx_kb = self.net_speed()
now = time.strftime("%Y-%m-%d %H:%M:%S")
# 负载均值
with open('/proc/loadavg') as f:
load = f.read().split()[:3]
print(f"\n{'='*60}")
print(f" 系统监控报告 --- {now}")
print(f"{'='*60}")
print(f" CPU 使用率: {cpu:5.1f}% "
f"负载: {load[0]} / {load[1]} / {load[2]}")
print(f" 内存使用率: {mem_pct:5.1f}% "
f"已用 {mem_used//1024} MiB / 共 {mem_total//1024} MiB")
print(f" 磁盘使用率: {disk_pct:5.1f}% "
f"已用 {disk_used} GiB / 共 {disk_total} GiB")
print(f" 网络 {self.iface}: "
f"↓ {rx_kb:6.1f} KB/s ↑ {tx_kb:6.1f} KB/s")
# 告警
alerts = []
if cpu > 80: alerts.append(f"CPU使用率 {cpu}% 过高")
if mem_pct > 85: alerts.append(f"内存使用率 {mem_pct}% 过高")
if disk_pct > 85: alerts.append(f"磁盘使用率 {disk_pct}% 过高")
if alerts:
print(f"\n ⚠️ 告警: {' | '.join(alerts)}")
else:
print(f"\n ✅ 所有指标正常")
if __name__ == '__main__':
monitor = SystemMonitor(iface='eth0')
print("=== Linux 综合系统监控(按 Ctrl+C 退出)===")
time.sleep(1) # 初始化网络采样基准
try:
while True:
monitor.report()
time.sleep(5)
except KeyboardInterrupt:
print("\n\n监控已停止。")
16. 监控工具对比总结
16.1 工具选型矩阵
| 场景 | 推荐工具 | 原因 |
|---|---|---|
| 快速查看 CPU/内存概览 | top / htop |
最通用,无需安装 |
| CPU 详细分析(每核、历史) | htop + sar |
htop 直观,sar 有历史 |
| 内存不足诊断 | free -h + vmstat + Python脚本 |
快速定位泄漏 |
| 磁盘 I/O 瓶颈定位 | iotop -o + iostat -x |
iotop 定进程,iostat 定设备 |
| 网络带宽占用分析 | nethogs + iftop |
nethogs 定进程,iftop 定连接对 |
| 网络包深度分析 | tcpdump |
无可替代,包级别分析 |
| 端口/连接状态查看 | ss -tlnp / netstat -tlnp |
ss 更现代更快 |
| 文件描述符溢出排查 | lsof |
定位"too many open files" |
| 企业级全面监控 | Nagios / Prometheus |
多主机、告警、历史 |
| 定制化监控 + 告警 | Python 脚本 |
灵活、可集成业务逻辑 |
| LAN 流量分布分析 | iptraf-ng |
按协议/端口的流量统计 |
16.2 /proc 文件系统速查
/proc/stat --- CPU 使用时间(vmstat/top 数据来源)
/proc/meminfo --- 内存详细统计(free 数据来源)
/proc/loadavg --- 系统负载均值(uptime 数据来源)
/proc/net/dev --- 网络接口收发统计(ifconfig 数据来源)
/proc/diskstats --- 磁盘 I/O 统计(iostat 数据来源)
/proc/net/tcp --- TCP 连接表(netstat 数据来源)
/proc/net/udp --- UDP 连接表
/proc/<PID>/status --- 进程详细状态(内存、线程数等)
/proc/<PID>/fd/ --- 进程打开的文件描述符(lsof 数据来源)
/proc/<PID>/net/ --- 进程网络命名空间(容器场景)
/proc/cpuinfo --- CPU 详细信息(型号、核数、频率)
16.3 性能告警阈值参考
| 指标 | 正常 | 告警 | 严重 |
|---|---|---|---|
| CPU 使用率 | < 70% | 70~90% | > 90% |
| 系统负载(n核) | < n×0.7 | n×0.7~n | > n |
| 内存使用率 | < 75% | 75~90% | > 90% |
| Swap 使用率 | 0% | > 0% | > 20% |
| 磁盘使用率 | < 75% | 75~90% | > 90% |
| 磁盘 I/O 延迟 | < 10ms | 10~50ms | > 50ms |
| 磁盘利用率 %util | < 60% | 60~80% | > 80% |
| 网络错误率 | 0 | > 0.1% | > 1% |
| TIME_WAIT 连接 | < 10000 | > 10000 | > 50000 |
| 文件描述符使用 | < 70% | 70~90% | > 90% |
附录:一键安装脚本
bash
#!/bin/bash
# Linux 监控工具一键安装(Ubuntu 24.04)
set -e
echo "=== 安装 Linux 系统监控工具集 ==="
apt-get update -qq
apt-get install -y \
htop \
sysstat \
iotop \
iftop \
nethogs \
tcpdump \
lsof \
net-tools \
iptraf-ng \
nload \
dstat \
glances
# 启用 sysstat 历史数据收集
sed -i 's/ENABLED="false"/ENABLED="true"/' /etc/default/sysstat 2>/dev/null || true
systemctl enable --now sysstat 2>/dev/null || true
echo ""
echo "已安装工具:"
echo " htop --- 交互式进程监控"
echo " sysstat --- iostat/sar/mpstat 工具集"
echo " iotop --- 磁盘 I/O 进程监控"
echo " iftop --- 网络带宽连接监控"
echo " nethogs --- 进程网络带宽监控"
echo " tcpdump --- 网络包捕获分析"
echo " lsof --- 打开文件列表"
echo " net-tools --- netstat/ifconfig 等"
echo " iptraf-ng --- LAN IP 流量监控"
echo " nload --- 网络接口带宽条形图"
echo " dstat --- 多维度系统统计(vmstat/iostat/netstat 集成)"
echo " glances --- Python 综合监控工具(类 htop 加强版)"
echo ""
echo "快速使用:"
echo " htop # 交互式进程监控"
echo " iostat -x 1 # 磁盘 I/O 实时统计"
echo " iotop -o # 有 I/O 的进程"
echo " nethogs eth0 # 进程带宽"
echo " iftop -i eth0 -n # 连接带宽"
echo " dstat -cdngy 1 # 综合统计"
echo " glances # 一体化监控"
文档生成时间:2026-06-20 | 实验环境:ecs-3bfd 集群(FlexusX x2e.8u.16g × 4)
内核版本:Linux 6.8.0-106-generic | Ubuntu 24.04 Server