自动化运维的关键支柱
一套高效的服务器监控脚本,是保障业务连续性、快速定位故障、优化资源利用的自动化核心工具,它通过持续采集关键性能指标、智能分析异常、及时触发告警,将运维人员从繁琐的手动检查中解放出来,实现主动式运维管理。

监控什么?核心指标是基石
全面而精准的监控始于对关键指标的识别,基础层面不可或缺的包括:
-
系统资源健康度:
- CPU使用率: 监控用户态、系统态、I/O等待、空闲时间占比。
top,vmstat,mpstat是数据源,持续高负载或I/O等待过长是瓶颈信号。 - 内存使用: 关注总量、已用、空闲、缓存/缓冲(buffers/cache)、交换分区(swap)使用情况。
free -m提供数据,Swap频繁使用或可用内存持续过低是风险点。 - 磁盘空间与I/O:
df -h监控各分区使用率(尤其根分区和关键数据分区)。iostat或iotop跟踪磁盘读写吞吐量(TPS)、响应时间(await)、利用率(%util),空间耗尽或I/O延迟陡增会直接影响服务。 - 网络流量:
ifconfig/ip或vnstat监控关键网卡入/出流量、包量、错误包/丢包率,带宽饱和或异常错误是网络问题的直接体现。 - 系统负载:
uptime输出的1分钟、5分钟、15分钟平均负载(Load Average)直观反映系统压力趋势(需结合CPU核心数解读)。
- CPU使用率: 监控用户态、系统态、I/O等待、空闲时间占比。
-
服务与应用可用性:
- 进程/服务状态:
ps,systemctl is-active service_name, 或检查进程PID文件(如/var/run/nginx.pid),确保关键应用(如Nginx, MySQL, Redis, 业务进程)持续运行。 - 端口监听:
netstat -tulnp或ss -tuln确认服务端口(如80, 443, 3306, 6379)处于正确监听状态。 - 应用层健康检查: 对Web服务执行HTTP(S)请求 (
curl -I -s -o /dev/null -w "%{http_code}" http://localhost/health),验证返回状态码(如200, 503);对数据库执行简单查询(mysql -e "SELECT 1;")。
- 进程/服务状态:
-
容易被忽视的关键点:
- 登录与安全: 监控
/var/log/auth.log或/var/log/secure中的异常登录尝试(如大量失败SSH登录)。 - 文件描述符:
sysctl fs.file-nr或检查/proc/sys/fs/file-nr,避免因FD耗尽导致服务崩溃。 - 僵尸进程:
ps aux | grep 'defunct'检查并告警。 - TCP连接状态:
netstat -an | grep tcp分析状态分布(如过多TIME_WAIT,CLOSE_WAIT,SYN_RECV可能有问题)。 - Inode使用率:
df -i,小文件过多可能导致磁盘空间未满但无法写入新文件。
- 登录与安全: 监控
如何构建?脚本编写实践指南

核心在于编写健壮、高效、可维护的Shell(Bash)或Python脚本,以Bash为例:
-
数据采集模块:
#!/bin/bash # 定义时间戳 TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S") # 采集CPU (使用vmstat取5秒内平均) CPU_USER=$(vmstat 1 2 | tail -1 | awk '{print $13}') CPU_SYSTEM=$(vmstat 1 2 | tail -1 | awk '{print $14}') CPU_IDLE=$(vmstat 1 2 | tail -1 | awk '{print $15}') CPU_IOWAIT=$(vmstat 1 2 | tail -1 | awk '{print $16}') # 注意列可能因系统而异 # 采集内存 (单位MB) MEM_TOTAL=$(free -m | awk '/Mem:/ {print $2}') MEM_USED=$(free -m | awk '/Mem:/ {print $3}') MEM_FREE=$(free -m | awk '/Mem:/ {print $4}') MEM_BUFFCACHE=$(free -m | awk '/Mem:/ {print $6}') # Buffers+Cache MEM_AVAILABLE=$(free -m | awk '/Mem:/ {print $7}') # 真正可用内存 SWAP_USED=$(free -m | awk '/Swap:/ {print $3}') # 采集根分区磁盘使用率 DISK_ROOT=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%') # 采集Load Average (1分钟) LOAD_1=$(uptime | awk -F 'load average:' '{print $2}' | awk -F, '{print $1}' | tr -d ' ') # 检查Nginx进程是否存在 NGINX_RUNNING=$(ps aux | grep -v grep | grep nginx | wc -l) # 检查MySQL端口(3306)是否监听 MYSQL_PORT_LISTENING=$(netstat -tuln | grep ':3306' | wc -l) # 检查Web服务HTTP状态码 (示例) HTTP_STATUS=$(curl -I -s -o /dev/null -w "%{http_code}" http://localhost) -
阈值判断与告警模块:
# 定义阈值 CPU_WARN=80 # CPU使用率警告阈值(%) MEM_WARN=90 # 内存使用率警告阈值(%) DISK_CRIT=90 # 磁盘使用率严重阈值(%) LOAD_WARN=4 # 1分钟负载警告阈值 (假设4核CPU) # 初始化告警信息变量 ALERT_MSG="" # CPU判断 (取用户+系统) CPU_TOTAL=$((CPU_USER + CPU_SYSTEM)) if [ $CPU_TOTAL -ge $CPU_WARN ]; then ALERT_MSG="${ALERT_MSG}【CPU高负载】当前使用率: ${CPU_TOTAL}% | " fi # 内存判断 (使用率 = (Total - Available) / Total 100) MEM_USAGE_PERCENT=$(( (MEM_TOTAL - MEM_AVAILABLE) 100 / MEM_TOTAL )) if [ $MEM_USAGE_PERCENT -ge $MEM_WARN ]; then ALERT_MSG="${ALERT_MSG}【内存高使用】当前使用率: ${MEM_USAGE_PERCENT}% | " fi # 磁盘判断 if [ $DISK_ROOT -ge $DISK_CRIT ]; then ALERT_MSG="${ALERT_MSG}【磁盘空间告急】根分区使用率: ${DISK_ROOT}% | " fi # 负载判断 if [ $(echo "$LOAD_1 > $LOAD_WARN" | bc) -eq 1 ]; then # 使用bc处理浮点数 ALERT_MSG="${ALERT_MSG}【系统负载高】1分钟负载: ${LOAD_1} | " fi # 服务状态判断 if [ $NGINX_RUNNING -eq 0 ]; then ALERT_MSG="${ALERT_MSG}【服务异常】Nginx进程未运行! | " fi if [ $MYSQL_PORT_LISTENING -eq 0 ]; then ALERT_MSG="${ALERT_MSG}【服务异常】MySQL端口3306未监听! | " fi if [ "$HTTP_STATUS" != "200" ]; then ALERT_MSG="${ALERT_MSG}【服务异常】Web服务HTTP状态码: ${HTTP_STATUS} | " fi -
告警触发模块:
# 如果有告警信息,则触发告警 if [ ! -z "$ALERT_MSG" ]; then # 1. 记录到本地日志 (重要!防止告警发送失败丢失信息) echo "[$TIMESTAMP] 告警: $ALERT_MSG" >> /var/log/server_monitor.log # 2. 发送邮件告警 (需配置邮件服务器或使用外部API) echo "服务器 [$HOSTNAME] 告警: $ALERT_MSG 时间: $TIMESTAMP" | mail -s "【服务器告警】$HOSTNAME" admin@example.com # 3. 集成企业微信/钉钉/Slack (推荐,更及时) # 示例: 使用curl调用企业微信机器人Webhook (需替换YOUR_WEBHOOK_URL) curl 'YOUR_WEBHOOK_URL' -H 'Content-Type: application/json' -d "{"msgtype": "text","text": {"content": "服务器[$HOSTNAME]告警: $ALERT_MSG 时间: $TIMESTAMP"}}" fi
超越基础:告警机制的优化策略
避免“狼来了”效应,提升告警有效性至关重要:

- 分级告警: 区分“警告”(Warning)与“严重”(Critical)级别,设置不同阈值和通知渠道(如严重级触发电话呼叫)。
- 告警收敛与抑制: 对同一主机同一问题的连续告警进行合并;在计划维护时段或已知故障处理期暂停非关键告警。
- 告警恢复通知: 当指标恢复正常时,自动发送恢复通知,确认问题已解决,增强信任。
- 依赖关系管理: 若下游服务故障导致上游告警(如数据库宕机引发Web服务503),优先通知根本原因,避免告警风暴。
- 告警升级机制: 设定时间窗口(如15分钟),若告警持续未被确认或解决,自动通知更高层级负责人。
持续进化:脚本的维护与迭代
监控脚本不是一劳永逸的:
- 集中化管理: 使用Ansible, SaltStack, Puppet部署和更新所有服务器上的监控脚本,确保配置一致性。
- 数据存储与可视化:
- 将脚本采集的数据发送到时序数据库(如 InfluxDB, Prometheus)。
- 利用 Grafana 等工具创建丰富的仪表盘,实现历史趋势分析、多维度数据关联。
- 对接专业监控系统: 脚本可作为Agent的补充,或通过标准协议(如Prometheus的 Pushgateway)将数据导入Zabbix, Nagios, Prometheus等平台,利用其强大的告警、事件管理、自动化处理功能。
- 日志监控集成: 使用 ELK Stack (Elasticsearch, Logstash, Kibana) 或 Loki 监控应用和系统日志,与性能指标关联分析。
- 定期审查与调优: 根据业务变化、新服务上线、历史告警分析,定期审查监控项、阈值、告警策略的有效性并进行优化。
精心设计与维护的服务器监控脚本,是运维自动化的基石,它赋予运维团队“千里眼”和“顺风耳”,变被动救火为主动防御,从核心指标监控到智能告警,再到与专业工具的整合,脚本的价值在于其灵活性、低成本和高效率,持续投入脚本的优化与迭代,构建稳固的监控防线,是保障业务顺畅运行的必由之路。
你的监控体系是否遇到过“告警疲劳”?在脚本设计或告警策略优化上,你有哪些独到的实战经验或踩过的坑?欢迎在评论区分享交流!
原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/14649.html