1. 课程导论:什么是告警驱动自愈、为什么需要数据库自愈、课程目标与前置知识
1.1 什么是告警驱动自愈
告警驱动自愈(Alert-Driven Self-Healing)是一种自动化运维模式:系统通过监控平台(如 Prometheus)持续采集指标,当指标触发预定义的告警规则时,不再仅通知工程师介入,而是由自动化脚本直接执行恢复操作,将系统拉回健康状态。
核心流程可概括为:指标采集 → 告警触发 → 脚本执行 → 状态验证 → 闭环通知。
关键区别:传统告警是“通知人”,告警驱动自愈是“通知系统自动恢复”。前者依赖人工响应,后者依赖预定义的恢复逻辑。
1.2 为什么需要数据库自愈
数据库是现代应用的核心状态层,其故障直接影响业务连续性。传统人工响应模式存在以下痛点:
| 痛点 | 典型场景 | 后果 |
|---|---|---|
| 响应延迟 | 凌晨 3 点连接数打满,DBA 30 分钟后才看到告警 | 业务中断 30+ 分钟,大量 5xx 错误 |
| 操作失误 | 手动执行 kill 命令时误杀正常连接 | 部分用户会话被强制中断 |
| 重复劳动 | 每周处理 5 次相同的“复制延迟”告警 | DBA 精力被低价值操作消耗 |
| 扩缩容滞后 | 流量突增时连接池未及时扩容 | 数据库连接耗尽,服务雪崩 |
数据参考:根据行业统计,数据库故障平均恢复时间(MTTR)在人工模式下约为 15-45 分钟;引入告警驱动自愈后,MTTR 可降至 30 秒-3 分钟,降低 90% 以上。
数据库自愈的核心价值在于:缩短 MTTR、减少人为失误、释放 DBA 生产力、提升系统 SLO。
1.3 课程目标
本课程旨在帮助学员掌握从零构建一套生产级“Prometheus 告警驱动数据库自愈系统”的完整能力。具体目标如下:
- 理解原理:掌握告警驱动自愈的架构设计、关键组件及数据流。
- 搭建监控:熟练配置 Prometheus + 数据库 Exporter + Alertmanager。
- 编写脚本:使用 Python 编写可复用的自愈脚本,涵盖 MySQL/PostgreSQL 常见故障场景。
- 安全防护:设计熔断、限频、灰度、回滚等安全机制,防止自愈脚本引发二次故障。
- 生产落地:完成从开发环境到生产环境的部署、测试与运维闭环。
| 章节模块 | 核心产出 |
|---|---|
| 监控搭建 | Prometheus + MySQL Exporter + Alertmanager 配置模板 |
| 脚本开发 | Python 自愈脚本框架(连接数/慢查询/复制延迟/磁盘空间) |
| 安全加固 | 熔断器、执行限频、告警去重、人工审批接口 |
| 测试与部署 | 混沌工程测试方案 + Docker Compose 一键部署 |
1.4 前置知识
为顺利学习本课程,建议学员具备以下基础:
提示:如果某项知识较为薄弱,课程附录提供了快速参考链接和复习材料。
| 领域 | 具体要求 | 学习建议 |
|---|---|---|
| Linux 基础 | 熟悉命令行、文件系统、进程管理、systemd 服务 | 能使用 grep/awk/sed 处理日志 |
| 数据库基础 | 了解 MySQL 或 PostgreSQL 基本概念(连接、查询、复制) | 能执行 SHOW PROCESSLIST; 或 pg_stat_activity 查询 |
| Python 基础 | 掌握变量、函数、异常处理、requests 库 | 能编写简单的 HTTP 请求和数据库查询脚本 |
| Prometheus 基础 | 了解指标采集、PromQL 基本查询、Alertmanager 规则 | 能配置一个简单的 CPU 告警规则 |
1.5 课程架构总览
本课程共 30 章,分为 6 个阶段,从原理到生产落地逐步深入:
1.6 一个简单的自愈脚本示例
为了让学员对最终产出有直观感受,下面展示一个极简的“MySQL 连接数超限自愈”脚本框架(完整版将在第 11 章展开):
#!/usr/bin/env python3
"""
alert_self_healing.py - 告警驱动自愈脚本示例
接收 Prometheus Alertmanager Webhook,自动 kill 空闲连接
"""
import json
import sys
import pymysql
def parse_alert(webhook_data):
"""解析告警数据,提取数据库实例和当前连接数"""
alert = webhook_data['alerts'][0]
labels = alert['labels']
return {
'instance': labels['instance'],
'db_host': labels['db_host'],
'db_port': int(labels['db_port']),
'current_connections': alert['annotations']['current_connections']
}
def kill_idle_connections(db_host, db_port, max_connections=200):
"""杀死空闲超过 60 秒的连接,直到连接数低于阈值"""
conn = pymysql.connect(host=db_host, port=db_port, user='admin', password='****')
with conn.cursor() as cursor:
cursor.execute("""
SELECT ID, USER, HOST, TIME
FROM information_schema.PROCESSLIST
WHERE COMMAND = 'Sleep' AND TIME > 60
ORDER BY TIME DESC
""")
idle_connections = cursor.fetchall()
killed = 0
for row in idle_connections:
if killed >= 10: # 每次最多 kill 10 个
break
cursor.execute(f"KILL {row[0]}")
killed += 1
conn.close()
return killed
def main():
webhook_data = json.loads(sys.stdin.read())
alert_info = parse_alert(webhook_data)
killed_count = kill_idle_connections(alert_info['db_host'], alert_info['db_port'])
print(f"Killed {killed_count} idle connections for {alert_info['instance']}")
if __name__ == '__main__':
main()
注意:以上代码仅为演示框架,生产版本需要加入熔断、日志、告警去重、人工审批等安全机制,这些内容将在课程第 19-23 章详细讲解。