如何基于 Cloud Run 标签实现灰度发布并双写数据库?
解读
在国内真实面试场景里,这道题常被用来同时考察候选人对 Serverless 流量治理与数据一致性的综合把控能力。
面试官真正想听的是:
- 你能否用 Cloud Run 的**标签路由(tag-based traffic splitting)**把线上流量按权重或用户维度切到灰度版本;
- 灰度版本在写 Cloud SQL 时,如何不破坏主库性能的前提下完成双写(主库+影子库/新库),并给出可回滚、可观测、可验证的完整闭环。
回答时务必把“灰度”与“双写”拆开讲:先让流量灰度,再让数据灰度,最后把两者用同一标签串起来,形成“流量+数据”一体的发布策略。
知识点
- Cloud Run 标签路由:通过
gcloud run services update-traffic把带标签的修订版本映射到具体百分比或 Header 规则,国内 VPC-SC 合规环境下同样生效。 - 双写模式:
– 同步双写:请求线程内先写主库、再写影子库,两次 commit 都成功才返回,延迟高、风险大;
– 异步双写:请求线程只写主库,通过Pub/Sub + Cloud SQL 只读实例或Datastream 把变更异步回放影子库,对主库零侵入;
– 折中方案:在灰度容器里用本地队列 + 有限重试,失败时把消息丢进Dead-letter Topic,人工补数。 - 数据一致性校验:用Cloud SQL 的 pglogical(PostgreSQL)或MySQL 的 checksum 表周期性对比主库与影子库,差异大于阈值自动回滚流量。
- 回滚策略:一旦校验失败或 SLO 告警,30 秒内把 Cloud Run 流量百分比重置到 0%,并关闭双写开关(Feature Flag),国内金融场景要求回滚时间 < 5 分钟。
- 可观测:
– 灰度版本自带自定义指标(opentelemetry)上报双写延迟、失败率;
– 用Cloud Monitoring 的 SLO + Alerting Policy 绑定 Cloud Run 标签维度,国内短信/飞书/钉钉通道对接 AlertManager。
答案
-
准备阶段
a. 在现有 Cloud Run 服务里新建修订版本v2-canary,注入环境变量ENABLE_DUAL_WRITE=true与SHADOW_INSTANCE_CONNECTION_NAME=project:region:shadow-db。
b. 为v2-canary打上标签canary,此时流量百分比保持 0%。 -
灰度流量
通过gcloud run services update-traffic prod-service --to-tags canary=5%把 5% 流量打到带canary标签的修订版本;国内合规要求先内部白名单再放量,可叠加 HeaderX-Cloud-Run-Tag: canary做员工狗食。 -
双写逻辑
在灰度代码里用连接池双实例:- 主库:照常写 Cloud SQL 主实例,事务提交后立即返回客户端;
- 影子库:把同一 SQL 语句放入内存 Channel(容量 2k),由独立 Goroutine 批量写影子实例;
- 若影子库超时或主键冲突,记结构化日志并推送到 Pub/Sub Topic
shadow-dual-write-dlq,不阻塞主流程。
-
一致性校验
每 10 分钟跑一次 Cloud SQL 的pt-table-checksum作业,对比主库与影子库;若差异行数 > 0.01%,自动调用gcloud run services update-traffic prod-service --to-tags canary=0%把流量清零,并发送钉钉告警。 -
回滚与清理
校验通过且灰度运行 24h 无异常后,把v2-canary提升为默认版本,关闭双写开关,并删除影子库只读实例以节省费用;若失败,30 秒内完成流量归零,保留影子库用于数据修复。
拓展思考
- 国内多活场景:如果业务已用Cloud SQL 跨区域高可用(北京/上海双实例),可把影子库直接建在对端区域,灰度发布同时验证跨区域复制延迟是否满足 RPO < 1 秒。
- 零信任安全:在私有 VPC-SC 边界内,Cloud Run 通过Private Service Connect 访问 Cloud SQL,双写流量不走公网;需给灰度版本单独配置服务身份(Service Identity) 与影子库的 IAM 授权,避免生产库权限泄露。
- 成本优化:影子库使用共享 CPU + 最小 1 vCPU 实例,只在灰度期间开启;校验完成后用Terraform 一键销毁,国内账号可叠加“抢占式实例”折扣进一步降本。