从入门到生产级实践指南
目录导读
- 引言:为什么需要服务器监控脚本
- 监控脚本的核心要素与设计原则
- 基础监控脚本编写(CPU、内存、磁盘)
- 网络与进程监控实战
- 日志分析与警报集成
- 生产级脚本的进阶技巧
- 常见问题与最佳实践问答
- 总结与推荐学习资源
为什么需要服务器监控脚本
在运维工作中,服务器宕机或性能瓶颈往往导致业务中断,尽管商业监控工具(如Zabbix、Prometheus)功能强大,但在定制化场景下,轻量级监控脚本更具灵活性,根据Stack Overflow 2023年调查,68%的运维工程师会编写自定义监控脚本以满足特定需求,本文将从零开始,教你编写一套可落地、可扩展的服务器状态监控脚本。

监控脚本的核心要素与设计原则
1 五大核心指标
- CPU使用率:避免过载导致响应延迟
- 内存占用:防止OOM(内存溢出)kill进程
- 磁盘I/O:监控读写延迟与空间使用率
- 网络连通性:检测端口与服务可用性
- 进程守护:确保关键进程常驻运行
2 设计原则
- 模块化:各指标独立函数,便于维护
- 幂等性:脚本多次执行不产生副作用
- 低侵入性:占用系统资源<5%
- 可穿戴性:支持T恤适配(不同Linux发行版)
基础监控脚本编写(CPU、内存、磁盘)
Bash实现示例
#!/bin/bash
# server_monitor.sh - 基础资源监控
# CPU使用率(取1分钟平均值)
cpu_load=$(awk -v RS='' '{print $0}' /proc/loadavg | awk '{print $1}')
cpu_percent=$(echo "scale=2; $cpu_load * 100 / $(nproc)" | bc)
# 内存使用率
mem_total=$(free -m | awk '/^Mem:/{print $2}')
mem_used=$(free -m | awk '/^Mem:/{print $3}')
mem_percent=$(echo "scale=2; $mem_used * 100 / $mem_total" | bc)
# 磁盘使用率(监控根分区)
disk_usage=$(df -h / | awk 'NR==2{print $5}' | sed 's/%//')
# 阈值告警
if (( $(echo "$cpu_percent > 80" | bc -l) )); then
echo "[WARN] CPU使用率异常: $cpu_percent%"
fi
关键知识点:
/proc/loadavg是内核实时状态文件bc命令处理浮点运算df -h输出人类可读的磁盘信息
网络与进程监控实战
1 端口存活检测(使用nc)
#!/bin/bash
check_port() {
local host=$1 port=$2
nc -zv -w 3 $host $port &>/dev/null
if [ $? -ne 0 ]; then
echo "[ALERT] 端口 $host:$port 不可达"
# 发送邮件或钉钉通知
fi
}
# 监控web服务
check_port "localhost" 80
check_port "api.example.com" 443
2 进程守护脚本
# 监控Nginx进程
process_name="nginx"
if ! pgrep -x "$process_name" > /dev/null; then
systemctl start nginx
echo "$(date) - 重启Nginx" >> /var/log/process_monitor.log
fi
进阶技巧:使用pgrep -c统计进程实例数,防范僵尸进程。
日志分析与警报集成
1 实时错误日志监控
# error_log_monitor.py - Python版本
import re
import subprocess
from datetime import datetime
ERROR_PATTERN = r"(ERROR|FATAL|Exception)"
LOG_FILE = "/var/log/app/app.log"
def tail_f():
with open(LOG_FILE, "r") as f:
f.seek(0, 2) # 移到文件末尾
while True:
line = f.readline()
if line and re.search(ERROR_PATTERN, line, re.I):
send_alert(line)
yield line
def send_alert(msg):
# 集成企业微信Webhook
webhook_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY"
data = '{"msgtype":"text","text":{"content":"%s"}}' % msg
subprocess.call(['curl', '-s', '-X', 'POST', '-H', 'Content-Type: application/json', '-d', data, webhook_url])
if __name__ == "__main__":
for line in tail_f():
pass
2 告警阈值配置表
| 指标 | 警告阈值 | 严重阈值 | 检查间隔 |
|---|---|---|---|
| CPU | >80% | >95% | 60s |
| 内存 | >85% | >93% | 120s |
| 磁盘 | >85% | >92% | 300s |
| 进程 | 缺失 | 缺失 | 30s |
生产级脚本的进阶技巧
1 并发采集与数据存储
使用Redis或InfluxDB存储时序数据:
import psutil
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
def push_metrics():
cpu = psutil.cpu_percent(interval=1)
mem = psutil.virtual_memory().percent
r.lpush('server:metrics', f"cpu:{cpu}|mem:{mem}|time:{int(time.time())}")
r.ltrim('server:metrics', 0, 999) # 保留最近1000条
2 异常自动修复逻辑
# 当磁盘占用>90%时自动清理临时文件
if [ $disk_usage -gt 90 ]; then
find /tmp -type f -atime +3 -delete 2>/dev/null
find /var/log -name "*.log" -size +100M -exec truncate -s 0 {} \;
fi
3 安全加固
- 脚本权限:
chmod 700 monitor.sh - 使用
setsid脱离终端依赖 - 关键路径写保护:
chattr +i /etc/scripts/
常见问题与最佳实践问答
Q1: 如何避免脚本自身消耗大量资源?
A:使用sleep控制检查频率,CPU监控时避免高频轮询,对于Python脚本,设置time.sleep(60);Bash脚本用sleep 120。
Q2: 监控脚本如何实现高可用?
A:部署双副本方案:
# crontab配置(每5分钟执行) */5 * * * * /opt/monitor/server_monitor.sh # 并在另一台服务器部署同名脚本,通过心跳互检
Q3: 需要监控上千台服务器怎么办?
A:采用分布式架构:
- 各服务器本地脚本采集数据
- 通过
rsyslog或Filebeat发送到中央收集器 - 使用
Elasticsearch存储+Kibana可视化
Q4: 脚本如何兼容不同Linux发行版?
A:检测包管理器:
if [ -f /etc/debian_version ]; then
PKG_CMD="apt-get"
elif [ -f /etc/redhat-release ]; then
PKG_CMD="yum"
fi
总结与推荐学习资源
通过本文,你已经掌握了从基础Bash脚本到生产级Python监控系统的完整构建方法,关键在于:
- 模块化设计:每个监控逻辑独立可复用
- 阈值动态调整:避免硬编码,支持热加载
- 告警降噪:聚合同类告警,防止告警风暴
延伸学习:
- 《Linux Performance Monitoring and Tuning》by Brendan Gregg
- Prometheus+Grafana官方文档
- GitHub开源项目:
node_exporter、telegraf
最后提醒:监控脚本需要持续迭代,建议建立版本控制(Git)和自动化测试(CI/CD),当你的脚本运行半年无故障后,可逐步引入容器化部署(Docker)和配置管理(Ansible)。
行动建议:立即在你的测试服务器上运行以下命令:
nohup bash -c "while true; do echo $(date) >> /var/log/my_monitor.log; top -bn1 | head -5 >> /var/log/my_monitor.log; sleep 30; done" &
然后通过tail -f /var/log/my_monitor.log实时观察系统状态。