蓝绿发布实践回顾
作者:得物技术 查看原文
缘起
随着蓝绿发布项目落地进入试运行,也对蓝绿发布项目做个简要回顾。
早在2022年初的时候效能、交易和中间件的同学就如何提高发布效率做过讨论,蓝绿发布当时也被提出。由于彼时有更重要的事情去落地,蓝绿发布也被搁置未能成行。
随着染色环境项目的落地,推进接入工作的基本完成。测试开发环境存在的众多问题(多套环境、运维问题、环境冲突、沟通问题)基本得到根治。
测试环境得到根治的同时,生产环境自然就成为接下来的重点。大版本发布时长达7个小时,的确是大家的痛点,我们也希望从根本上提高发布效率。本文主要内容有:
- 应用发布诉求
- 发布方案对比
- 蓝绿发布流程
- 蓝绿流量调度
- 组件能力支持
应用发布诉求
微服务应用发布时有以下诉求:
- 上下游依赖:本服务的发布依赖其他服务,要别的服务先发布才行
- 小流量灰度:发布时先小流量灰度验证、避免问题被放大
- 按批次发布:支持节点批次划分、按批次发布
其中上下游依赖问题最为突出,为解决依赖问题需提前填写发布计划,将应用组织成梯队来规避上下游依赖问题。
- 填写发布计划较为繁琐:每次发布需要去组织填写、比较繁琐
- 必须按照梯队顺序发布:一个梯队发完才能发布另一个梯队、需要互相等待
- 应用回滚稳定性需提升:一个应用验证有问题,需要依赖上游联动回滚,回滚过程中有生产流量、稳定性存在优化空间
由此可见,应用发布的痛点聚焦到了破除上下游上,自然解决方案也以此为中心。
发布方案对比
发布方式 | 基本原理 | 常见实现 |
灰度发布 | 小流量验证 | 方式一:金丝雀发布,发布时先拉入一台验证,正常后发布剩余节点 方式二:流量染色灰度,通过对请求流量染色选择到特定的节点实现灰度 方式三:独立灰度环境,上线前先在该环境验证(例如:小得物环境) |
滚动发布 | 分批次发布 | 在灰度验证的基础上,通过发布系统选择发布批次 方式一:按节点比例分批发布 方式二:按节点数量分批发布 |
蓝绿发布 | 流量调度实现 | 线上同时蓝绿两个应用组提供服务 步骤一:新版本发布时先将流量从蓝色集群A调度到绿色集群B,绿色集群B独立承担流量 步骤二:在蓝色集群A发布新版本,从小到大逐步引流到蓝色集群 步骤三:蓝色验证正常均衡蓝绿两套流量,异常流量调度走即可 |
红黑发布 | 弹性扩缩容、流量调度 | 线上只运行一个红色集群 步骤一:发布时先扩容黑色集群,该集群发布新版本 步骤二:在黑色集群发布新版本,按比例引流验证 步骤三:一切正常后,流量调度到黑色集群,红色集群下线 |
熟悉中间件运维的同学怎么运维才是安全的呢?先摘流、运维变更、再逐步引流。
这种方式应用到应用发布系统,即为蓝绿发布。
在生产环境发布时,我们通常有两个版本,线上运行的版本、待发布的版本。
也就是在生产环境区分流量只需要两个颜色即可,蓝绿发布通过两个染色流量来区分线上运行版本和待发布版本。
此外,希望在大版本发布与日常迭代中都能使用蓝绿发布来提效,作为核心应用的首选发布方式。
蓝绿发布流程
在发布系统中集成蓝绿发布,与普通发布有何区别,蓝绿发布流程是怎么样的呢?
3.1 蓝绿架构图示
线上的资源容量需能够容纳业务增量的2倍以上,将线上的运行的服务节点资源一分为二,分成蓝色环境和绿色环境。
3.2 蓝绿发布流程
为了避免混淆将蓝绿环境固定,先部署待发布新版本的环境固定为「蓝色环境」,后部署待发布新版本的环境固定为「绿色环境」,应用发布先发「蓝色环境」,后发「绿色环境」。
发布流程梳理如下:
- 将蓝色集群摘流,此时流量被染绿进入绿色集群
- 系统发布时先经过「蓝色环境」,后发布「绿色环境」
- 应用上下游服务在「蓝色环境」集中完成部署
- 引入1%流量蓝色流量验证
- 「蓝色环境」上下游服务验证「不符合预期」,流量切换到绿色环境
- 「蓝色环境」完成验证「符合预期」,全部流量染成蓝色,流量调度到了蓝色环境
- 此时绿色环境已无流量,新版本在绿色环境集中完成部署
- 通过递进式引流到绿色环境【1%~50%】
- 最后呈现的流量分布,蓝绿流量各50%
纵观整个发布流程,需要众多部门和组件的联动配合才能完成,下到容器、上到网关,中间贯穿众多核心中间件。
蓝绿流量调度
在设计流量调度时分为全局流量调度与局部流量调度,分别应对不同的发布场景。
全局流量调度(单通道发布):所有蓝绿环境的应用都参与流量调度,适用一次发布上百个应用场景、上下游关系难以梳理。
局部流量调度(多通道发布):适用于已知应用依赖发布、日常迭代。
在已知应用依赖的情况下,通过局部流量调度即可满足需求。
4.1 全局流量调度
上面提到「全局流量单通道」在蓝绿环境的服务均会参与调度,流量调度变更涉及全部在蓝绿环境的应用,下面以流量全部调度蓝色环境为例观测各个组件的行为。
伴随着绿色环境被摘流,流量全部在蓝色环境运行。
- RPC选择本环境对应节点、并提供兜底选择策略
- 绿色环境应用消息组被下线摘除消费流量、同时在蓝色环境唤醒绿色消费组接管流量
- 配置中心应用只访问对应蓝绿环境的配置集
- 分布式调度此时只调度到蓝色环境
4.2 局部流量调度
「局部流量多通道」的流量调度比例,由各通道进行自行管控。如下图所示:
- 全局流量单通道:蓝绿切流比例 50%:50%
- 局部流量多通道1 :蓝绿切流比例 5%:95%
- 局部流量多通道2 :蓝绿切流比例 0%:100%
- 局部流量多通道3 :蓝绿切流比例 70%:30%
需要注意的是
- 一个应用只允许在一个发布通道发布,避免流量冲突和干扰
- 当「全局流量单通道」发布与「局部流量多通道」同时发布时
- 以「局部流量多通道」比例为准
- 「局部流量多通道」发布结束后,会被「全局流量单通道」流量比例接管
4.3 调度实现原理
无论是「全局流量单通道」调度还是「局部流量多通道」调度,实现原理都是一样的,下面以RPC调用为例说明,如下图所示。
工作原理简述如下:
- @1 由发布系统即将【通道标识、包含的应用列表、切流比例】写入元数据中心
- @2 「局部流量多通道」中的应用收到蓝绿比例。例如:图示中应用A收到自身所属通道的蓝绿流量比例
- @3 「局部流量多通道」中的应用将自身的蓝绿比例写入注册中心。例如:应用A将自身蓝绿流量比例写入注册中心
- @4 调用应用A的【所有上游应用】通过注册中心均收到应该调用A的蓝绿流量比例。例如:应用B、应用C、应用D均收到应该调用应用A的蓝绿比例
- @5 上游应用按流量比例向下游服务发起调用
从流量调度和实现原理来看,流量的调度会与RPC、消费组、分布式调度、发布系统、配置中心、注册中心一起联动。需要把存在的流量出口(例如:网关、消息、分布式调度等)流量管控起来。
组件能力支持
上文中提到流量的调度涉及到众多组件联动与协同,那各个组件需要提供哪些能力呢?下面介绍下这些组件需提供的能力。
5.1 容器逻辑分组
蓝绿发布离不开容器的逻辑分组,应用使用蓝绿发布之前,需要将应用的机器实例分布到蓝绿环境中去。容器需要具备的能力如下:
- 提供应用蓝绿逻辑分组
- 蓝绿标识植入环境变量
- 应用分组发布系统可见
如下图所示,应用通过容器分组,分布到蓝绿集群。
5.2 发布系统支持
发布系统是整个蓝绿发布的入口,用户直接感受的系统。对下与容器交互、对上与元数据中心交互。
- 提供蓝绿发布多通道能力,将本次发布关联应用拉入同一发布通道
- 提供蓝绿发布流水线、流量调操作
- 根据容器平台提供的逻辑分组接口、指定蓝绿集群发布
- 将通道信息、应用列表、流量调度信息写入元数据中心,供中间件感知
如下图所示,将整个蓝绿发布形成流水线。
5.3 统一框架支持
统一框架包含流量调度SDK、与注册中心和配置中心交互,联动整个RPC、Feign/HTTP流量调度。
- 优先根据蓝绿标,选择本环境节点调用
- 根据权重路由策略选择下游节点
- 提供兜底策略,避免无节点可选
节点选择示意图如下:
如下图所示,框架会将蓝绿环境信息与权重在注册中心注册。
5.4 消息组件支持
消息组件根据流量调度SDK的回调,需要将消费流量摘除和激活。
逻辑实现约定如下:
- 蓝绿环境各使用三个消费组 melon-consumer、BLUE-melon-consumer、GREEN-melon-consumer
- 消费组melon-consumer用于消费无(蓝绿)标识的流量,蓝绿标识会在每条消息属性中存储
- 消费组__BLUE-melon-consumer用于消费「蓝色」标识流量
- 消费组__GREEN-melon-consumer用于消费「绿色」标识流量
蓝绿两个环境均有流量:
- 绿色环境melon-consumer 、**_**GREEN-melon-consumer参与消费;BLUE-melon-consumer下线不参与消费
- 蓝色环境melon-consumer 、**_**BLUE-melon-consumer参与消费,GREEN-melon-consumer下线不参与消费
只有绿色环境有流量时:
- 绿色环境melon-consumer、**_**GREEN-melon-consumer参与消费,BLUE-melon-consumer被动态唤醒参与消费,未被消费完的蓝色流量被接管
- 蓝色环境GREEN-melon-consumer、BLUE-melon-consumer、melon-consumer均被动态下线,不参与消费
只有蓝色环境有流量时:
- 绿色环境**_**GREEN-melon-consumer、BLUE-melon-consumer、melon-consumer均被动态下线,不参与消费
- 蓝色环境**_**GREEN-melon-consumer、BLUE-melon-consumer、melon-consumer均参与消费,其中__GREEN-melon-consumer被动态唤醒,接管未被消费的绿色流量
如下图所示,蓝绿消费组消费各自对应的消息:
此外,DTS等组件同步的消息会被「无前缀标记的消费组(例如:melon-consumer)」接管,能够在100%流量调度时摘除消费流量。
5.5 配置中心支持
配置中心提供能的能力,主要蓝绿环境的节点选择与其对应的配置集,涉及到SDK和配置中心集群的改动。
- 配置中心提供蓝色配置集
- 蓝色环境应用选择蓝色版本配置集
- 绿色环境应用选择绿色版本配置集
- 提供兜底策略、无蓝绿版本时选择主版本配置集
如下图所示,配置中心提供蓝绿不同的版本的配置集。
5.6 网关调用支持
- 读取注册中心节点流量调度比例
- 提供根据流量比例选择下游节点的策略,例如:通过节点权重加权计算
如下图所示,流量全部切换到蓝色集群后,网关向下游分发的流量染蓝。
5.7 分布式调度支持
- 通过命名空间区分蓝绿环境调度
- 一次调度只在一个环境进行,避免两个环境同时发生调度,对业务影响
- 支持按照调度中心百分比(100%切流时)执行调度
- 支持输入蓝绿环境,手动执行到特定环境
如下图所示,在调度时选择对应蓝绿环境的节点。
5.8 蓝绿监控看板
蓝绿发布进行流量调度时,需要有一个可观测面板观察HTTP、DUBBO、MQ等的流量比例以及是否被摘流。
如下图看板所示HTTP流量,蓝色流量占比10%,绿色流量占比90%。
后记
蓝绿发布通过摘流、变更、再引流,因在无流量的情况下发布,相对比较安全。但是基于公司实际情况,有些场景的流量是无法摘除的。
- 未通过网关进入服务流量:例如:通过域名SLB进入服务、通过Ingress进入服务的流量无法摘除
- 消费Kafka的流量无法摘除:由于应用使用的原生kafka客户端并全面铺开、无法对切入提供支持
- 未使用统一框架/注册中心:未使用统一框架和Sylas注册中心的java应用、以及非Java类应用当前不支持蓝绿发布
此外,还有一些注意事项在使用蓝绿发布时需警惕。
- 消费消息需幂等:使用消息中间件必须做幂等,这是基本要求,在消费组启停管控中可能产生重复消息
- 消费组线程数量:由于会有三个消费组、消费线程也会增加两倍,有业务影响时需调低线程数
- 需要好流量评估:蓝绿发布需一半节点承接线上流量、在应用升级蓝绿集群时做好确认
- 升级到特定版本:使用蓝绿发布需要应用升级到框架指定版本
- Feign/HTTP流量:针对使用框架Feign的HTTP流量,需上下游应用全部升级后方可使用
- 使用Dubbo流量:使用框架Dubbo的服务只需要自身服务升级版本即可、无需上下游升级