如何编写环境检测与修复脚本

wen 实用脚本 1

从入门到自动化运维

目录导读

  1. 为什么需要环境检测与修复脚本?
  2. 核心设计原则:检测-修复-验证闭环
  3. 基础检测命令与日志采集技巧
  4. 条件判断与异常处理机制
  5. 自动修复策略与回滚方案
  6. 定时任务与监控告警集成
  7. 实战案例:数据库空间不足自动清理
  8. 常见问题与安全加固建议

为什么需要环境检测与修复脚本?

在运维与DevOps实践中,环境故障(如磁盘写满、服务宕机、依赖缺失)往往造成业务中断。人工排查耗时且易遗漏,而脚本化处理能实现:

如何编写环境检测与修复脚本

  • 秒级响应:通过cron或systemd timer定时触发,替代人工巡检
  • 一致性修复:避免不同工程师操作差异导致的新问题
  • 审计可追溯:每次修复动作记录日志,便于复盘

问:脚本检测与监控工具(如Zabbix)有何区别? 答:监控工具负责“发现异常并告警”,而修复脚本则聚焦“自动处置并恢复”,两者互补,脚本应作为监控告警后的最后一道自动防线


核心设计原则:检测-修复-验证闭环

优秀的修复脚本不能只“做了”,还要“确认做对了”,遵循以下三步闭环:

graph LR
A[检测] -->|异常触发| B[修复]
B --> C[验证]
C -->|未恢复| B
C -->|恢复成功| D[记录日志并退出]

关键点

  • 幂等性:修复操作无论执行几次,结果一致(确保目录存在”而非“创建目录”)
  • 超时控制:防止修复命令本身卡死(使用timeout 10包裹)
  • 分级处理:轻故障尝试自动修复,重故障停止操作并报警

基础检测命令与日志采集技巧

不同环境的检测命令需封装为函数,便于复用,以Bash为例:

check_disk_usage() {
    local threshold=$1 # 如 85
    local usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
    if [ $usage -gt $threshold ]; then
        echo "WARN: Disk usage ${usage}% exceeds ${threshold}%"
        return 1
    else
        echo "INFO: Disk usage ${usage}% normal"
        return 0
    fi
}

日志采集

  • 统一使用loggertee -a /var/log/env_repair.log
  • 记录时间戳、执行用户、退出码
  • 建议采用JSON格式,便于ELK等系统解析

条件判断与异常处理机制

脚本必须区分“可修复”与“不可修复”场景,建议采用状态机模式

def main():
    state = "check"
    while state != "exit":
        if state == "check":
            state = "repair" if is_broken() else "exit"
        elif state == "repair":
            state = "verify" if attempt_repair() else "alert"
        elif state == "verify":
            state = "exit" if is_healthy() else "repair"
        elif state == "alert":
            send_sms("人工介入")
            state = "exit"

陷阱提醒

  • 避免set -e导致未知错误提前退出;建议使用set +e后用判断
  • 修复动作前必须备份原配置(如cp /etc/app.conf /etc/app.conf.bak

自动修复策略与回滚方案

修复策略应遵循“最小权限”和“渐进式修复”原则:

级别 策略 示例
L1 无副作用操作 清理临时文件、重启服务
L2 需谨慎操作 修改配置文件、删除旧日志
L3 高影响操作 重装软件包、格式化分区(需人工确认标志文件存在)

回滚机制

# 修复前
cp /opt/myapp/config.ini /opt/myapp/config.ini.$(date +%s)
# 若验证失败
mv /opt/myapp/config.ini.bak /opt/myapp/config.ini
systemctl restart myapp

定时任务与监控告警集成

将脚本接入cron(注意环境变量PATH):

*/5 * * * * /usr/local/bin/env_check.sh >> /var/log/env_repair.log 2>&1

告警集成:脚本执行异常退出码(如2)时,通过webhook推送至钉钉/企业微信:

if exit_code != 0:
    requests.post(webhook_url, json={"msg": f"修复失败,需人工介入"})

实战案例:数据库空间不足自动清理

场景:MySQL binlog占满磁盘,导致服务不可写。

脚本核心代码(Python伪代码):

import shutil, subprocess
def get_mysql_data_disk_usage():
    return shutil.disk_usage("/var/lib/mysql")
def purge_binlog():
    subprocess.run(["mysql", "-e", "PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;"])
def main():
    if get_mysql_data_disk_usage().percent > 85:
        print("Disk usage > 85%, purging old binlogs...")
        purge_binlog()
        # 验证
        if get_mysql_data_disk_usage().percent < 60:
            print("Recovery successful")
        else:
            raise Exception("Purge failed, consider archive logic")

关键细节binlog_expire_logs_seconds与手动清理结合,避免误删在线日志。


常见问题与安全加固建议

常见错误

  • ❌ 脚本中硬编码IP和密码(应使用环境变量或密钥管理服务)
  • ❌ 无限重试导致负载飙升(应设最大重试次数,如3次)
  • ❌ 忽略系统dependencies(如bcjq未安装)

加固建议

  1. 使用shellcheck静态分析脚本语法
  2. 脚本内嵌入版本号(如VERSION=1.2.0)便于追踪
  3. 关键操作前检查run_lock文件防止并发执行
  4. 对输出进行脱敏(避免打印密码、token)

Q&A 精华汇总

  • 问:脚本用Bash还是Python? 答:简单检查用Bash(依赖少);复杂逻辑如正则匹配、操作数据库用Python(可读性强)。
  • 问:如何测试脚本可靠性? 答:采用Docker模拟故障环境,配合fault injection工具(如tc模拟网络丢包)进行混沌测试。

环境检测与修复脚本是运维的“自动驾驶仪”,其核心在可靠性与控制风险之间平衡,建议从简单场景(磁盘空间)入手,逐步覆盖服务、网络、依赖等层面,最后提醒:任何自动修复都无法替代完善的备份策略——修复之前,先保住数据

抱歉,评论功能暂时关闭!