AWS 排障、备份恢复与成本控制
# AWS 排障、备份恢复与成本控制
先用证据确认失败层级,再改最小范围;先证明能恢复,再考虑清理资源。
# 按请求路径排查,不按报错名称猜
| 症状 | 第一个检查点 | 下一步 |
|---|---|---|
| 浏览器报 CORS | 原始 HTTP 状态和网关响应 | 先排除上游 4xx/5xx,再检查 Origin 配置 |
| ALB 4xx,但应用没日志 | ELB 自身指标与 Target 指标 | 请求可能还没到应用,不先改业务路由 |
| 公网读正常、内部调用失败 | 内部 DNS、Cloud Map 注册、VPC DNS 属性 | 核对内部路径,不把公网成功当成私网成功 |
| Stack 更新失败 | Events 中最早的具体失败资源 | Resource update cancelled 往往是连带结果 |
| 镜像推送成功,线上没变化 | Stack 参数、Task revision、实际 digest | 推镜像和更新运行服务是两个阶段 |
| 数据库连接失败 | DNS、路由、安全组、TLS、凭据 | 不通过关闭证书校验或开放公网 “修好” |
原项目曾因部署角色缺少 Logs/CloudWatch 的具体权限导致回滚。CloudFormation 的控制面权限不代表所有底层服务权限。正确路径是根据失败 action 补最小授权、恢复 Stack 状态,再重新部署,而不是附加管理员策略。
# 无副作用的身份与状态检查
在本地已经配置受控只读 profile 后运行;命令不打印 Secret value,也不创建或删除资源。
# 先确认实际身份与账号;profile 名只是示例,不能据此假定权限安全。
aws sts get-caller-identity --profile notes-readonly
# 查询精确 Stack 的事件,按时间查看失败位置;不要把完整生产输出公开粘贴。
aws cloudformation describe-stack-events \
--profile notes-readonly --region us-east-2 \
--stack-name example-api \
--query 'StackEvents[].{Time:Timestamp,Resource:LogicalResourceId,Status:ResourceStatus}'
2
3
4
5
6
7
知道失败位置后,在受控环境查看相应 Reason;其中可能包含资源标识,应先脱敏再用于公开复盘。
# 有备份文件,为什么还不够
备份需要同时覆盖数据、结构、版本、恢复依赖与解密能力。只有数据库 dump,可能缺少 Secret、队列未处理事件、对象文件或基础设施配置;只有加密包,没有可恢复密钥,也无法使用。
| 证据层 | 能证明什么 | 不能证明什么 |
|---|---|---|
| 文件存在 | 保存过一个文件 | 内容完整且可恢复 |
| checksum 一致 | 当前副本与记录的字节一致 | 备份内容本来就是正确的 |
| 工具能列出内容 | 格式可读 | 全部表与数据能成功恢复 |
| 隔离环境恢复成功 | 数据与结构在该环境可还原 | 应用权限、外部依赖与业务都正常 |
| 应用回读与流程验证 | 恢复后的系统满足选定验收项 | 所有未测试业务都没有问题 |
# 一次恢复演练的顺序
- 记录备份时间、来源版本、工具版本与资源清单,归档加密并保留受控的独立副本。
- 验证文件校验和以及解密能力,不在日志里显示密钥或数据内容。
- 在隔离环境恢复数据库结构与数据,验证迁移记录、关键行数与业务约束。
- 恢复应用配置和必要对象,执行脱敏样本的回读与端到端检查。
- 记录恢复耗时、丢失的数据窗口和未覆盖项,确认是否符合业务目标。
RPO(Recovery Point Objective)表示最多能接受丢多久的数据;RTO(Recovery Time Objective)表示最多能接受多久恢复服务。例如每小时备份一次不自动意味着 RPO 一小时,还要看备份是否成功和恢复链是否完整。
原项目恢复 PostgreSQL 时曾遇到旧 pg_restore 无法识别新 dump 格式。应优先匹配备份工具版本,并验证目标服务器兼容性,不把解析失败直接认定为备份损坏。
DynamoDB 的 JSON 能解析、条数正确,只证明离线材料可读,不等于已经向目标表恢复;还要处理结构、索引、未处理写入项、权限与业务回读。不要把两种验证写成同一个 “恢复完成” 。
# 用时间线算清 RPO 和 RTO
假设 14:00 发生故障,最后一个验证可恢复的时间点是 13:50,15:00 恢复业务并验证通过。实际可能损失的窗口是 10 分钟,实际恢复耗时是 60 分钟;要分别与事先约定的 RPO、RTO 比较。二者是目标,不是备份工具自动保证的结果。
若发现问题花了 20 分钟、准备环境 15 分钟、还原数据 15 分钟、验证切流 10 分钟,RTO 不能只报还原数据库的 15 分钟。备份频率也不等于实际可恢复时间点,日志归档失败、密钥不可用都会把数据窗口拉大。
# 恢复时如何避免把事故再执行一次
恢复数据库后立即启动所有消费者,可能让旧消息再次付款、发邮件或改订单。应先隔离外部写操作,核对数据库备份与队列、对象存储、链上记录的时间边界,再决定补放哪些事件。
例如备份里订单仍是待付款,但支付方显示已收款,不能重新扣款;应按业务操作 ID 对账并修复本地状态。Web3 也是一样,恢复数据库不会撤销链上交易,需按链上事实重建投影。
演练至少验证普通读取、一个受控写入、异步处理和幂等重放,并记录哪些依赖未覆盖。测试环境的支付和通知应替换为隔离目标,不能把恢复演练变成重复触达真实用户。
# 跨账号迁移与删除的边界
迁移顺序是:确认可恢复备份 → 目标资源重建 → 数据恢复 → 验证业务与异步链路 → 切流 → 观察 → 明确批准后清理源资源。清理必须按精确资源清单,不按模糊前缀批量删除。
云加密资源的跨账号恢复还涉及 KMS key policy、快照共享、Secret 重建和目标角色授权;账号迁移不能只复制 CloudFormation 文件。本文不提供一键删除脚本,也不把历史备份视为当前数据的有效备份。
# 成本从哪里来
| 类别 | 常见费用来源 | 怎么控制 |
|---|---|---|
| 常驻基础设施 | NAT、ALB、数据库、常驻 Task | 先估固定成本,再决定共享、缩容与实验时长 |
| 按使用计费 | Lambda、消息、API、模型调用 | 限并发、重试、预算和无效调用 |
| 存储与观测 | 日志、快照、镜像、对象与自定义指标 | 保留策略、生命周期、采样与低基数维度 |
| 网络 | 公网出站、跨 AZ/Region、NAT 数据处理 | 看完整数据路径,不只比较计算单价 |
停止服务不一定等于零费用:快照、存储、网络设施可能仍计费;某些托管资源停止后还会按服务规则重新启动。免费额度也受套餐、地区、日期和资格限制,不把旧笔记中的固定优惠数字当作长期承诺。
费用异常先定位服务、Region、标签和时间,再决定动作。不要为了某项服务不可用就自动升级账号计划、建立 Organizations 或创建新账号。
# 成本优化先算单位业务成本
总账单由固定成本和按量成本共同组成。低流量时,数据库、ALB、NAT 和常驻 Task 可能是主要开销;高流量时,请求、模型 Token、日志和网络传输更值得关注。具体金额随区域和服务价格变化,应查实际账单,不使用一套永久固定数字。
可以统计 “每个成功报告的总成本” ,把失败重试、队列等待期间的常驻资源和观测费用也计入。只看一次模型调用价格,会漏掉重试三次和闲置 GPU 的成本。
优化后同时复测延迟和恢复能力。例如 Worker 缩到 0 省常驻费用,却增加启动等待;缩短日志保留节省存储,却可能失去事故调查证据。预算告警只是通知,真正限额还需要受控并发、任务预算和服务级保护,不能依赖告警自动停费。
# 面试时可以这样回答
怎么证明备份真正有效?参考答案
我不只检查文件存在,而是校验完整性、解密能力和工具兼容,在隔离环境恢复数据与结构,再验证应用能回读关键业务。最后记录恢复时间、数据窗口和缺失依赖,核对 RTO、RPO。只有这些证据齐全,才讨论切流或删除源资源。
数据库恢复成功,为什么还不能马上开放业务?参考答案
数据库只是系统的一部分,支付、对象存储和消息可能已经走到了不同时间点。我会先隔离写操作,验证结构、权限和关键回读,再按业务 ID 对账,避免重放已经完成的付款。异步和幂等链路也通过后才切流,恢复完成要以业务验收为准。
云成本突然上涨,先做什么?参考答案
先按服务、区域、时间和资源标签定位增长项,再关联请求量、重试、日志和发布变化。如果是异常重试,优先止住放大源;如果是固定资源闲置,再评估缩容。不能直接批量删除,也不能只减计算费用却让延迟和恢复目标失守。
# 复用来源与参考
整理自原项目 Go 排障章节、运行手册与备份恢复记录;真实账号、资源、备份 ID、存储位置和历史清理结果未迁入公开文档。