本文目录导读:

- 基于
uptime或/proc/loadavg检测 CPU 负载(最简单) - 结合 CPU 使用率和内存使用率(更全面)
- 检测磁盘 I/O 负载(使用
iostat) - 综合检测脚本(推荐:Nginx 服务器监控示例)
- 如何持续监控与告警
- 最佳实践与注意事项
脚本检测服务器负载过高通常需要结合 CPU、内存、磁盘 I/O、网络 等核心指标,并定义一个合理的阈值(CPU 使用率持续 > 80% 或负载均值 > CPU 核心数*0.7)。
以下是几种常用的脚本实现方案(以 Linux 系统为主):
基于 uptime 或 /proc/loadavg 检测 CPU 负载(最简单)
uptime 会显示过去 1 分钟、5 分钟、15 分钟的平均负载,通常负载值与 CPU 核心数比较,若连续 5 分钟负载高于核心数,则判定为负载过高。
Bash 脚本示例:
#!/bin/bash
# 获取CPU核心数
cores=$(nproc)
# 获取过去5分钟的平均负载 (取整数部分)
load_5min=$(awk '{print $2}' /proc/loadavg | cut -d '.' -f1)
# 判断:如果5分钟平均负载超过核心数*0.7,则认为负载过高
threshold=$(echo "$cores * 0.7" | bc | awk '{print int($1)}')
if [ "$load_5min" -ge "$threshold" ]; then
echo "[WARNING] CPU负载过高: 5min平均负载为 ${load_5min},核心数为 ${cores},阈值为 ${threshold}"
# 这里可以执行告警动作,比如发送邮件、写入日志
else
echo "[OK] 负载正常: 5min平均负载为 ${load_5min}"
fi
结合 CPU 使用率和内存使用率(更全面)
使用 top、vmstat 或 free 命令采集数据。
Python 脚本示例(使用 psutil 库,推荐):
import psutil
import time
# 定义阈值
CPU_THRESHOLD = 80.0 # CPU使用率超过80%
MEM_THRESHOLD = 90.0 # 内存使用率超过90%
def check_load():
cpu_percent = psutil.cpu_percent(interval=1)
mem_percent = psutil.virtual_memory().percent
alarms = []
if cpu_percent > CPU_THRESHOLD:
alarms.append(f"CPU使用率过高: {cpu_percent}%")
if mem_percent > MEM_THRESHOLD:
alarms.append(f"内存使用率过高: {mem_percent}%")
if alarms:
print("[WARNING] " + " | ".join(alarms))
# 发送告警至钉钉/邮箱等
else:
print("[OK] CPU: {:.1f}%, 内存: {:.1f}%".format(cpu_percent, mem_percent))
if __name__ == "__main__":
check_load()
检测磁盘 I/O 负载(使用 iostat)
高磁盘 I/O(特别是 await 或 %util 高)也可能导致整体服务响应慢。
Bash 脚本示例:
#!/bin/bash
# 需要安装 sysstat: apt install sysstat -y
iostat -x 1 2 | tail -n +4 | head -1 | while read device r_await w_await svctm util; do
# 示例:util超过90%则告警
if (( $(echo "$util > 90" | bc -l) )); then
echo "[WARNING] 磁盘I/O负载过高: ${device} 的 %util=${util}"
fi
done
综合检测脚本(推荐:Nginx 服务器监控示例)
同时检测:CPU、内存、磁盘空间、网络连接数。
#!/bin/bash
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
# 1. CPU 负载
cores=$(nproc)
load_5min=$(awk '{print $2}' /proc/loadavg | cut -d '.' -f1)
threshold=$((cores * 70 / 100)) # 70% 负载阈值
# 2. 内存使用率
mem_total=$(free -m | awk '/^Mem:/{print $2}')
mem_used=$(free -m | awk '/^Mem:/{print $3}')
mem_percent=$((mem_used * 100 / mem_total))
# 3. 磁盘使用率 (检查根分区)
disk_usage=$(df / | awk 'NR==2{print $5}' | tr -d '%')
# 4. 网络连接数 (ESTABLISHED)
connections=$(ss -t state established | wc -l)
echo "=== 系统负载检查 ==="
echo "CPU核心数: $cores | 5min平均负载: $load_5min | 阈值: $threshold"
echo "内存: ${mem_used}MB/${mem_total}MB (${mem_percent}%)"
echo "磁盘: ${disk_usage}%"
echo "TCP连接数: ${connections}"
# 判断是否告警
alarm=""
if [ "$load_5min" -ge "$threshold" ]; then
alarm="${alarm}CPU负载过高(负载$load_5min) "
fi
if [ "$mem_percent" -ge 90 ]; then
alarm="${alarm}内存使用率过高(${mem_percent}%) "
fi
if [ "$disk_usage" -ge 90 ]; then
alarm="${alarm}磁盘使用率过高(${disk_usage}%) "
fi
if [ -n "$alarm" ]; then
echo -e "${RED} !!! 告警: $alarm ${NC}"
# 此处可添加发送至钉钉/企业微信/邮件的代码
else
echo -e "${GREEN} 所有指标正常。${NC}"
fi
如何持续监控与告警
脚本本身是单次检测,若要实现持续监控,可以使用 Crontab 定时执行:
# 每2分钟执行一次检测脚本 */2 * * * * /usr/local/bin/check_load.sh
或者部署为 systemd 服务 配合 while 循环。
最佳实践与注意事项
| 维度 | 常用阈值参考 | 注意事项 |
|---|---|---|
| CPU 使用率 | > 80% 持续 5 分钟 | 区分用户态/系统态,高 iowait 也可能是磁盘问题 |
| 内存使用率 | > 90% | 需检查是否缓存占用过高(Linux 会尽量使用空闲内存做缓存) |
| 磁盘 I/O(%util) | > 90% | 使用 SSD 时阈值可提高至 95% |
| 平均负载 | > 核心数 × 0.7 | 1 分钟负载高可能只是瞬发,建议以 5 分钟或 15 分钟为准 |
| TCP 连接数 | 视服务而定 | Web 服务器可监控 ESTABLISHED 数量 |
重要提示:
- 不要仅凭 CPU 使用率判断:高负载也可能由磁盘 I/O 等待(iowait)引起。
- 区分正常突发与持续高负载:建议脚本中增加“持续次数检测”(例如连续 3 次均超过阈值才告警),避免误报。
- 生产环境建议使用成熟工具:如
Prometheus + Node Exporter + AlertManager或Zabbix,脚本作为轻量级补充或初期验证。
如果你需要特定环境(如 Windows、Docker 容器内)的检测脚本,或者需要集成第三方告警(钉钉、邮件),可以进一步说明需求。