3. 巡检脚本基础:作用、常见对象与自动化价值
巡检脚本是容量压测与 Capacity Planning 体系中的“感知层”。没有巡检脚本,压测后的数据就像没有仪表的驾驶舱——你只知道系统在跑,却不知道它是否正在逼近极限。本节从巡检脚本的核心作用出发,逐一拆解 CPU、内存、磁盘、网络四大巡检对象,并阐明自动化巡检如何将“救火式运维”转变为“可预测的容量管理”。
3.1 巡检脚本的核心作用
巡检脚本不是简单的“检查一下系统状态”,它在容量压测流程中承担三个关键角色:
| 角色 | 说明 | 容量规划中的意义 |
|---|---|---|
| 基线采集器 | 在压测前、中、后固定时间点采集系统指标 | 提供“正常态 vs 压力态”的对比基线,用于判断容量拐点 |
| 异常哨兵 | 实时检测指标是否超过预设阈值,触发告警或熔断 | 防止压测打垮生产环境,保护业务连续性 |
| 趋势记录器 | 将每次巡检结果持久化到时序数据库 | 支撑 Capacity Planning 的长期趋势分析与资源预测模型 |
关键认知: 巡检脚本不是“一次性检查工具”,而是容量数据管道的起点。没有标准化的巡检脚本,后续的容量建模、趋势预测、成本优化都无从谈起。
3.2 四大巡检对象详解
容量压测场景下,巡检对象必须覆盖计算、存储、网络三大资源域。以下逐一说明每个对象的巡检指标、常见命令与容量关注点。
3.2.1 CPU 巡检
CPU 是容量规划中最敏感的指标。巡检脚本需要区分 用户态 (us)、系统态 (sy)、等待 I/O (wa)、空闲 (id) 和 软中断 (si) 等细分状态。
| 指标 | 采集命令 | 容量关注点 |
|---|---|---|
| CPU 使用率 (整体) | top -bn1 | grep "Cpu(s)" |
超过 80% 持续 5 分钟以上,需评估扩容 |
| 用户态 vs 系统态 | mpstat -P ALL 1 1 |
系统态过高 (>30%) 可能表示锁竞争或系统调用瓶颈 |
| CPU 负载 (load average) | uptime |
load > 核数×0.7 时,系统进入过载区 |
| 上下文切换 | vmstat 1 3 |
cs 列 > 100000 可能触发调度抖动 |
3.2.2 内存巡检
内存巡检不仅要看总量,更要关注 实际可用内存 和 内存回收压力。
| 指标 | 采集命令 | 容量关注点 |
|---|---|---|
| 总内存 / 已用 / 可用 | free -m |
可用内存低于总内存 10% 时触发预警 |
| Swap 使用量 | free -m | grep Swap |
Swap 使用 > 0 表示物理内存不足,必须扩容 |
| 缓存 / 缓冲区 | cat /proc/meminfo |
缓存过高可能掩盖真实内存压力,需结合 page fault 判断 |
| OOM Killer 事件 | dmesg | grep -i "oom" |
出现 OOM 表示内存已严重超卖,立即扩容 |
3.2.3 磁盘巡检
磁盘是容量压测中最容易被忽略的瓶颈。巡检脚本必须同时关注 容量 和 性能 两个维度。
| 维度 | 指标 | 采集命令 | 容量关注点 |
|---|---|---|---|
| 容量 | 磁盘使用率 | df -h |
使用率 > 85% 需规划扩容或清理 |
| inode 使用率 | df -i |
inode 耗尽会导致无法创建文件,即使磁盘还有空间 | |
| 性能 | IOPS (读写) | iostat -x 1 3 |
r/s + w/s 接近磁盘标称 IOPS 上限时,出现排队 |
| 吞吐量 (MB/s) | iostat -dm 1 3 |
顺序读写接近磁盘带宽上限时,延迟会急剧上升 | |
| I/O 等待时间 (await) | iostat -x 1 3 |
await > 20ms (机械盘) 或 > 5ms (SSD) 表示磁盘饱和 |
3.2.4 网络巡检
网络巡检在分布式压测场景下尤为重要。除了带宽,还需要关注 TCP 连接状态 和 丢包率。
| 指标 | 采集命令 | 容量关注点 |
|---|---|---|
| 网络带宽使用率 | sar -n DEV 1 3 |
rxkB/s + txkB/s 接近网卡带宽 80% 时,需考虑链路聚合或升级 |
| TCP 连接数 (ESTABLISHED) | ss -s |
连接数超过系统上限 (net.core.somaxconn) 会导致连接拒绝 |
| TCP 重传率 | netstat -s | grep retrans |
重传率 > 2% 表示网络质量下降,影响压测吞吐 |
| 丢包率 | ping -c 100 -i 0.01 target |
丢包 > 0.1% 时,压测结果不可信,需排查网络链路 |
3.3 自动化巡检的价值
手工巡检在单机场景下尚可应付,但在分布式压测环境中(动辄几十上百台节点),自动化巡检的价值体现在以下四个层面:
- 一致性保障: 所有节点使用相同的采集命令、相同的采样间隔、相同的阈值规则,消除人为操作差异。
- 时间对齐: 自动化脚本可以在所有节点上同时启动采集,确保压测过程中的指标在时间轴上严格对齐,这是容量建模的基础。
- 持续记录: 每次压测的巡检数据自动写入时序数据库,形成可回溯的容量历史,支撑 Capacity Planning 的长期趋势分析。
- 异常自愈: 当巡检脚本检测到指标超过危险阈值时,可以自动触发熔断(如停止压测、摘除节点),保护生产环境。
实践建议: 自动化巡检脚本应设计为“幂等且无状态”。每次执行只采集数据并上报,不修改系统配置。这样即使脚本被频繁调用,也不会对系统产生副作用。
3.4 巡检脚本与容量规划的整合关系
下图展示了巡检脚本在容量压测与 Capacity Planning 整合流程中的位置:
3.5 一个完整的巡检脚本示例
以下是一个生产级巡检脚本的核心片段,覆盖 CPU、内存、磁盘、网络四大对象,并输出结构化的 JSON 数据,便于后续写入时序数据库:
#!/bin/bash
# 容量压测巡检脚本 - 单次采集示例
# 输出格式:JSON,每条记录一行
TIMESTAMP=$(date +%s)
HOSTNAME=$(hostname)
# CPU 采集
CPU_USER=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
CPU_SYSTEM=$(top -bn1 | grep "Cpu(s)" | awk '{print $4}' | cut -d'%' -f1)
CPU_IDLE=$(top -bn1 | grep "Cpu(s)" | awk '{print $8}' | cut -d'%' -f1)
LOAD_1=$(uptime | awk -F'load average:' '{print $2}' | cut -d',' -f1 | xargs)
# 内存采集
MEM_TOTAL=$(free -m | awk '/^Mem:/{print $2}')
MEM_USED=$(free -m | awk '/^Mem:/{print $3}')
MEM_AVAILABLE=$(free -m | awk '/^Mem:/{print $7}')
SWAP_USED=$(free -m | awk '/^Swap:/{print $3}')
# 磁盘采集(以根分区为例)
DISK_USAGE=$(df -h / | awk 'NR==2{print $5}' | cut -d'%' -f1)
DISK_IO_UTIL=$(iostat -x 1 1 | awk '/^[a-z]/{if(NR==4) print $NF}')
# 网络采集
NET_RX=$(sar -n DEV 1 1 | grep "eth0" | awk '{print $5}')
NET_TX=$(sar -n DEV 1 1 | grep "eth0" | awk '{print $6}')
TCP_ESTAB=$(ss -s | grep "estab" | awk '{print $2}')
# 输出 JSON
echo "{
\"timestamp\": $TIMESTAMP,
\"host\": \"$HOSTNAME\",
\"cpu\": {
\"user\": $CPU_USER,
\"system\": $CPU_SYSTEM,
\"idle\": $CPU_IDLE,
\"load_1m\": $LOAD_1
},
\"memory\": {
\"total_mb\": $MEM_TOTAL,
\"used_mb\": $MEM_USED,
\"available_mb\": $MEM_AVAILABLE,
\"swap_used_mb\": $SWAP_USED
},
\"disk\": {
\"root_usage_pct\": $DISK_USAGE,
\"io_util_pct\": $DISK_IO_UTIL
},
\"network\": {
\"rx_kbps\": $NET_RX,
\"tx_kbps\": $NET_TX,
\"tcp_established\": $TCP_ESTAB
}
}"
注意: 以上脚本为单次采集示例。生产环境中应加入超时控制(timeout)、错误重试、日志记录和并发锁,防止多个压测任务同时运行时脚本冲突。
3.6 自动化巡检的常见陷阱与避坑
- 陷阱一:采集命令本身成为性能瓶颈。 例如在磁盘 I/O 已经很高时,再执行
iostat -x 1 1会额外增加 I/O 负载。解决方案:降低采集频率,或使用 /proc/diskstats 直接读取内核计数器。 - 陷阱二:时间不同步导致数据错位。 多节点巡检时,如果 NTP 未对齐,同一时间戳的指标可能来自不同的真实时间点。解决方案:在巡检脚本中统一使用 NTP 同步后的系统时间,并在数据管道中做时间戳对齐。
- 陷阱三:阈值硬编码导致误报。 不同业务场景的容量阈值不同(例如数据库服务器 vs Web 服务器)。解决方案:将阈值配置化,通过环境变量或配置文件注入,避免修改脚本本身。
- 陷阱四:忽略巡检脚本自身的资源消耗。 脚本本身会占用 CPU、内存和磁盘 I/O。解决方案:在压测前先对巡检脚本做一次“自检”,确保其资源消耗不超过总资源的 1%。