数据库切换、可用区故障和网络路径抖动,往往不是架构图上最难的一部分。真正困难的是证明应用在这些事件发生时会按照预期工作。Google Cloud Fault Injection Testing(FIT)在预览阶段提供了原生的故障注入能力,让开发者和架构师可以用实验模板自动化定义故障、目标资源、持续时间和恢复动作。
为什么需要原生故障注入
在自建数据中心中,团队通常可以直接控制主机、网络设备和存储层,从而模拟节点或链路故障。云环境隐藏了大量底层基础设施,应用团队很难仅靠脚本制造一个可信的可用区故障。
这会在可靠性策略中留下一个空白:团队可能知道系统“设计上支持”故障转移,却没有验证过真实的切换过程。风险包括:
- 故障期间性能下降,持续损害客户信任。
- 无法提供灾难恢复能力的证据,增加审计和合规压力。
- 大规模迁移被迫暂停,因为团队无法证明关键服务能承受可用区故障。
- 告警、连接池、重试和回滚机制在真实故障中同时暴露问题。
FIT 的价值不在于制造混乱,而在于把故障演练变成有边界、可审计、可以重复执行的实验。
FIT 的实验模型
FIT 使用实验模板作为故障演练的蓝图。模板需要描述故障类型以及会被影响的资源。当前预览摘要中包含两类主要场景:
- Cloud SQL 故障转移:触发高可用 Cloud SQL 实例从主可用区切换到备用可用区。
- 降低应用流量质量:通过第 7 层负载均衡器,选择性增加延迟或返回 HTTP 错误码。
执行故障前,FIT 会自动运行 dry run。这个只读模拟会检查操作者权限,并列出当前实验可能影响的资源。团队可以先确认范围,再手动启动注入。
实验持续时间由模板定义。计时结束后,故障会被恢复;如果监控显示风险超出预期,也可以使用 stop and revert 能力立即停止实验并开始恢复资源。
这种流程把一次演练拆成几个明确的控制点:
准备模板 -> dry run 检查权限和影响范围 -> 人工确认 -> 注入故障
-> 观察指标、日志和业务行为 -> 到期自动恢复或手动 stop/revert
从非生产环境开始
预览阶段适合在非生产环境中建立流程。环境应尽量接近生产拓扑,否则演练结果只能说明测试环境的行为。
可以这样准备一个最小实验:
- 使用与生产相同的应用版本、连接超时、重试策略和健康检查配置。
- 准备一个高可用 Cloud SQL 实例,或一个由第 7 层负载均衡器承载的测试服务。
- 确认实验账号只拥有执行所需的
roles/faulttesting.operator角色及必要的基础资源权限。 - 为实验设置明确的持续时间、停止条件和负责人。
- 在注入前记录基线:请求成功率、P95/P99 延迟、错误率、数据库连接数和队列积压。
下面是一组可改造的初始化命令。由于 FIT 处于预览阶段,服务标识、实验资源字段和 CLI 子命令可能随预览版本变化;运行前请以当前 Google Cloud 控制台或用户指南中的名称为准。命令中的项目和账号均为占位值。
#!/usr/bin/env bash
set -euo pipefail
PROJECT_ID="replace-with-nonprod-project"
REGION="replace-with-region"
OPERATOR="group:reliability@example.com"
# 选择非生产项目并确认当前身份
gcloud config set project "$PROJECT_ID"
gcloud auth list
# 预览阶段请在控制台搜索并启用 “Fault Testing API”。
# 如果当前版本公开了对应服务标识,可使用类似命令:
# gcloud services enable <fault-testing-api-service-name> --project="$PROJECT_ID"
# 授予 FIT 操作员角色。请先确认组织的 IAM 审批流程和资源范围。
gcloud projects add-iam-policy-binding "$PROJECT_ID" \\
--member="$OPERATOR" \\
--role="roles/faulttesting.operator"
# 运行实验前,先在 Cloud Console、gcloud 或 REST API 中创建模板并执行 dry run。
printf 'Ready for FIT dry run: project=%s region=%s operator=%s\\n' \\
"$PROJECT_ID" "$REGION" "$OPERATOR"
如果团队通过代码管理实验定义,可以把模板内容纳入代码审查。下面是一个概念性的模板草稿,字段名仅用于说明应该固化哪些信息,不能直接视为当前 FIT API 的完整请求格式:
{
"name": "cloud-sql-failover-nonprod",
"target": {
"project": "replace-with-nonprod-project",
"region": "replace-with-region",
"cloudSqlInstance": "replace-with-ha-instance"
},
"fault": {
"type": "CLOUD_SQL_FAILOVER"
},
"duration": "300s",
"approval": {
"requireDryRun": true,
"stopConditions": [
"error_rate_above_threshold",
"database_connections_exhausted"
]
}
}
实际实验中,先执行 dry run 并保存影响资源清单,再启动故障注入。不要把“模板创建成功”当成“应用具备高可用能力”;真正需要验证的是业务请求是否继续成功、客户端是否正确重连,以及告警和自动化恢复是否及时触发。
观察什么,如何判定成功
故障演练需要提前定义通过标准。以 Cloud SQL 故障转移为例,可以检查:
- 应用是否只出现可接受范围内的短暂错误。
- 数据库客户端是否能够在连接失效后重新建立连接。
- 重试是否带有退避,避免切换期间形成请求风暴。
- 读写流量是否仍然到达正确的数据库端点。
- 告警是否在预期时间内触发,并且包含足够的上下文。
对于负载均衡器注入延迟或 HTTP 错误,可以观察:
- 超时设置是否小于实验持续时间,并且符合业务操作的实际容忍度。
- 服务是否区分可重试错误和不可重试错误。
- 熔断、限流和降级页面是否按设计工作。
- 依赖服务的错误是否被正确传播、聚合和追踪。
实验报告至少应记录实验模板版本、目标资源、dry run 结果、故障开始和结束时间、关键指标、告警事件、业务影响以及后续修复项。这样,故障演练才能从一次手工操作变成持续可靠性工程的一部分。
采用时的边界
FIT 预览提供了接近真实故障的验证路径,但它不是灾难恢复策略的替代品。团队仍然需要单独验证备份恢复、跨区域恢复、数据一致性、容量余量和业务级切换流程。
采用前可以用下面的清单检查准备度:
- [ ] 项目已获得预览访问权限。
- [ ] 已启用 Fault Testing API。
- [ ] 操作人员已获得
roles/faulttesting.operator及所需资源权限。 - [ ] 第一次实验安排在非生产环境。
- [ ] 模板包含明确的目标资源和持续时间。
- [ ] 已完成 dry run,并审阅影响范围。
- [ ] 已设置停止条件、监控面板和人工负责人。
- [ ] 实验结果能够转化为配置修复、代码修复或架构改进。
比较稳妥的落地顺序是先验证 Cloud SQL 故障转移,再验证流量延迟和 HTTP 错误,最后把通过标准和实验报告接入日常发布或灾难恢复演练。故障注入只有在可观测、可停止、可复盘时,才真正有助于提高服务可靠性。