# 第36天:运维综合实战——故障排查与应急响应 ## 今天你将学到什么 今天是第五阶段的收尾。我们通过模拟真实的生产故障场景,把监控、日志、告警、恢复等知识串联起来,学习如何系统化地排查和解决问题。 --- ## 故障排查的基本方法论 ### OODA 循环 军事领域的决策模型,同样适用于故障排查: ``` Observe(观察)→ Orient(定位)→ Decide(决策)→ Act(行动) ↑ ↓ └──────────────── 循环 ←───────────────────────┘ ``` 1. **观察**:收集信息。看监控、看日志、看告警 2. **定位**:分析问题在哪里。是网络?应用?数据库? 3. **决策**:确定修复方案。重启?回滚?扩容? 4. **行动**:执行修复。验证是否恢复 --- ## 故障场景一:网站突然变慢 ### 用户反馈 "网站加载要 10 秒以上,之前只要 1 秒。" ### 排查过程 **第一步:看 CloudWatch 仪表板** ``` 发现: - ALB 的 TargetResponseTime 从 200ms 飙升到 8000ms - EC2 的 CPU 使用率正常(30%) - 内存使用率正常(50%) ``` CPU 和内存都正常,但响应很慢。问题不在计算资源。 **第二步:看数据库指标** ``` 发现: - RDS 的 DatabaseConnections 达到上限(100/100) - RDS 的 ReadLatency 从 5ms 飙升到 2000ms - 活跃查询数异常高 ``` 数据库连接数满了!新请求拿不到连接,只能等待。 **第三步:看 CloudWatch Logs** 在应用日志中搜索 "timeout" 或 "connection": ``` [ERROR] Could not get database connection from pool: timeout after 5000ms [WARN] Slow query detected: SELECT * FROM orders WHERE status='pending' - 3500ms ``` 找到了一个慢查询! **第四步:定位根因** 查看最近的部署记录(CloudTrail): ``` 发现:2 小时前有一次部署,新代码中有一个查询没有加索引, 导致全表扫描。随着数据量增长,查询越来越慢,最终拖垮了连接池。 ``` ### 修复方案 ``` 紧急修复(5 分钟内恢复): 1. 回滚到上一个版本(CodeDeploy 一键回滚) 2. 验证响应时间恢复正常 根本修复(之后处理): 1. 给 orders 表的 status 字段加索引 2. 修复代码中的查询 3. 加入慢查询监控告警 4. 重新部署 ``` --- ## 故障场景二:服务完全不可用 ### 告警触发 CloudWatch 告警:ALB 的 HealthyHostCount = 0(没有健康的后端实例) ### 排查过程 **第一步:检查 EC2 实例状态** ``` 发现: - Auto Scaling Group 中有 3 台实例 - 所有实例状态都是 "running" - 但 ALB 健康检查全部失败 ``` 实例在运行,但应用不健康。 **第二步:SSH 登录实例查看** ``` 发现: - 应用进程在运行 - 但磁盘空间 100% 满了 - 应用无法写入日志文件,导致崩溃 ``` **第三步:确认原因** ``` 发现: - 昨天开启了 DEBUG 级别日志(为了排查另一个问题) - 忘记关闭了 - DEBUG 日志量巨大,一晚上写满了 50GB 磁盘 ``` ### 修复方案 ``` 紧急修复: 1. 清理旧日志文件,释放磁盘空间 2. 将日志级别改回 INFO 3. 重启应用 4. 验证健康检查通过 预防措施: 1. 设置磁盘使用率告警(> 80% 就通知) 2. 配置日志轮转(logrotate),自动清理旧日志 3. 将日志发送到 CloudWatch Logs,不依赖本地磁盘 4. 制定规范:DEBUG 日志只在开发环境开启 ``` --- ## 故障场景三:费用异常暴涨 ### 告警触发 Budget 告警:本月费用已达预算的 300% ### 排查过程 **第一步:Cost Explorer 分析** ``` 发现: - EC2 费用暴涨 10 倍 - 来自 us-east-1 区域 - 实例类型:p3.8xlarge(GPU 实例,$12/小时) ``` 你的团队从来不用 GPU 实例,也不在 us-east-1 工作。 **第二步:CloudTrail 查看谁创建的** ``` 发现: - 用户 "dev-intern" 的 Access Key 在凌晨 2 点从境外 IP 创建了 20 台 GPU 实例 - 这些实例在挖矿 ``` 账号被盗了! ### 修复方案 ``` 紧急修复: 1. 立刻禁用 dev-intern 的 Access Key 2. 终止所有异常的 EC2 实例 3. 检查是否有其他异常资源 安全加固: 1. 所有用户强制启用 MFA 2. 设置 IAM 策略限制可创建的实例类型 3. 设置 Service Control Policy 限制可使用的区域 4. 启用 GuardDuty 检测异常行为 5. 联系 AWS Support 申请费用减免 ``` --- ## 应急响应流程 ### 标准化的应急流程 ``` 1. 发现(Detection) - 监控告警触发 - 用户报告问题 - 自动化检测发现异常 2. 响应(Response) - 确认问题严重程度 - 通知相关人员 - 组建应急小组 3. 缓解(Mitigation) - 执行紧急修复(回滚、扩容、切换) - 目标:尽快恢复服务,不一定要找到根因 4. 恢复(Recovery) - 确认服务完全恢复 - 验证数据完整性 - 监控是否有复发 5. 复盘(Post-mortem) - 时间线:什么时候发生了什么 - 根因分析:为什么会发生 - 改进措施:怎么防止再次发生 - 不追责,重改进 ``` ### 应急工具箱 | 场景 | 工具 | 操作 | |------|------|------| | 应用出错 | CodeDeploy | 一键回滚到上一版本 | | 流量暴涨 | Auto Scaling | 手动调高最大实例数 | | 数据库过载 | RDS | 添加只读副本分担压力 | | 安全事件 | IAM | 禁用被盗账号的凭证 | | 区域故障 | Route 53 | 切换 DNS 到备用区域 | --- ## 运维最佳实践总结 ### 事前准备 1. **完善的监控**:关键指标都有监控和告警 2. **自动化恢复**:能自动恢复的不要等人工 3. **定期演练**:模拟故障,验证恢复流程 4. **文档化**:常见问题的排查步骤写成 Runbook 5. **备份验证**:定期验证备份能否成功恢复 ### 事中响应 1. **先恢复,后排查**:用户体验优先 2. **沟通透明**:及时通知相关方进展 3. **记录时间线**:为复盘留下证据 4. **避免二次故障**:修复操作要谨慎 ### 事后改进 1. **无责复盘**:关注系统改进,不追究个人 2. **改进措施落地**:每次复盘的改进项要有人跟进 3. **分享经验**:让整个团队从故障中学习 --- ## 今天的小测验 1. 网站变慢时,排查的第一步应该看什么? 2. 为什么说"先恢复,后排查"? 3. 如果发现 AWS 账号被盗,应该立刻做什么? 4. 故障复盘的目的是什么?为什么强调"无责"? --- ## 延伸阅读 - [AWS 故障排查指南](https://docs.aws.amazon.com/systems-manager/latest/userguide/troubleshooting.html) - [AWS Incident Manager](https://docs.aws.amazon.com/incident-manager/latest/userguide/) - [AWS Fault Injection Simulator](https://docs.aws.amazon.com/fis/latest/userguide/) --- ## 明天预告 进入第六阶段:进阶与认证。明天开始学习 AWS 认证考试的准备策略,以及如何系统化地复习前面学到的所有知识。