蓝绿部署适合主版本升级、数据库结构不变的全量切换,灰度发布适合功能迭代、需验证用户行为或下游兼容性的渐进式发布;service selector切换后流量未生效的主因是readinessprobe失败或超时过短,导致pod未就绪而无法加入endpoints。

蓝绿部署和灰度发布不是“选一个”,而是“什么时候用哪个”——蓝绿适合主版本升级、数据库结构不变的全量切换;灰度适合功能迭代、需验证用户行为或下游兼容性的渐进式发布。
Service selector 切换蓝绿时,为什么流量没立刻生效
常见错误是 selector 更新后 Pod 没进 Endpoints,根本原因是 readinessProbe 失败或超时太短。Kubernetes 不会把未就绪的 Pod 加入 Service 的后端列表,哪怕 Deployment 已 Ready。
-
readinessProbe必须探测真实依赖(DB ping、Redis GET、gRPC HealthCheck),不能只返回{"status":"up"} -
timeoutSeconds至少设为3,避免慢启动 Pod 被反复踢出;initialDelaySeconds不可靠,建议在 Go 启动逻辑里加time.Sleep(2 * time.Second)等初始化完成再开放/readyz - 切流命令要用
kubectl patch service xxx -p '{"spec":{"selector":{"version":"v2"}}}',别用kubectl apply -f全量覆盖——容易冲掉 CI 注入的git-commit等 label - 确认生效:运行
kubectl get endpoints xxx,看 IPs 是否已变成 green Pod 的地址;再查kubectl describe service xxx,确认Selector字段已更新
灰度发布中 Golang 服务怎么识别分流规则
关键不在 Go 代码里写路由逻辑,而在于让网关或客户端负载均衡器能读到版本元数据,并把规则透传过来。Golang 服务只需解析并响应。
- 注册到 Consul/Nacos 时,在服务元数据里加
version=v1和gray=false;新版本注册为version=v2、gray=true - HTTP 请求头透传:Nginx/Kong/Traefik 配置
proxy_set_header x-version $version或根据 cookie / query 参数注入 header - Golang 中统一中间件提取:
r.Header.Get("x-version")或r.URL.Query().Get("v"),用于日志打标或触发差异化逻辑(如 mock 数据、跳过风控) - 不要在 handler 里实时做灰度决策——所有分流应在网关或 client-side balancer 层完成,Go 服务只做“被动适配”
数据库不兼容时,蓝绿部署一定会失败
蓝绿要求新旧版本共存期间,数据库 schema 必须向前兼容。比如 v2 新增字段不能设 NOT NULL,删除字段不能直接 DROP COLUMN,否则 v1 会写失败。
- DDL 变更必须拆成两步:先加字段(允许 NULL)、改应用代码兼容;等蓝绿切换完成、v1 下线后再删旧字段
- 如果用了 gorm.AutoMigrate,务必关掉自动建表/改表,生产环境只允许手动执行 SQL 迁移脚本
- 迁移脚本本身要幂等,且必须在 green 环境部署前、Pod 启动前执行(例如用 InitContainer 或 Job)
- 回滚时,仅切回流量不够——v1 无法读写 v2 写入的新字段,所以数据库也要同步回滚(或保留兼容层)
真正卡住蓝绿落地的,从来不是 YAML 怎么写,而是 /readyz 是否真能反映 DB 连通性、Shutdown 是否等完 Kafka 消费者、以及数据库迁移有没有和流量切换对齐时间点。这些细节不验证,切流那一刻就是故障开始的时间。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











