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}'
1
2
3
4
5
6
7

知道失败位置后,在受控环境查看相应 Reason;其中可能包含资源标识,应先脱敏再用于公开复盘。

# 有备份文件,为什么还不够

备份需要同时覆盖数据、结构、版本、恢复依赖与解密能力。只有数据库 dump,可能缺少 Secret、队列未处理事件、对象文件或基础设施配置;只有加密包,没有可恢复密钥,也无法使用。

证据层 能证明什么 不能证明什么
文件存在 保存过一个文件 内容完整且可恢复
checksum 一致 当前副本与记录的字节一致 备份内容本来就是正确的
工具能列出内容 格式可读 全部表与数据能成功恢复
隔离环境恢复成功 数据与结构在该环境可还原 应用权限、外部依赖与业务都正常
应用回读与流程验证 恢复后的系统满足选定验收项 所有未测试业务都没有问题

# 一次恢复演练的顺序

  1. 记录备份时间、来源版本、工具版本与资源清单,归档加密并保留受控的独立副本。
  2. 验证文件校验和以及解密能力,不在日志里显示密钥或数据内容。
  3. 在隔离环境恢复数据库结构与数据,验证迁移记录、关键行数与业务约束。
  4. 恢复应用配置和必要对象,执行脱敏样本的回读与端到端检查。
  5. 记录恢复耗时、丢失的数据窗口和未覆盖项,确认是否符合业务目标。

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、存储位置和历史清理结果未迁入公开文档。