作者:丛霄、章进、十眠
微服务架构下的灰度发布
微服务链路的复杂性
微服务典型的业务架构模式具有松耦合,可被独立开发、部署以及扩缩容等特点。在项目初期,整个业务规模较小,整个系统还在有条不稳地设计测试运行,服务间的调用关系也比较明确。随着业务规模逐渐扩大,链路调用关系越来越复杂,整个系统的稳定性变得岌岌可危。
其中生产发布灰度过程作为稳定性中重要的一环而备受关注,复杂的功能要能支持完备的灰度能力。面对复杂的微服务调用链路环境,为保证稳定性,业务的上线前往往需要经过详细的测试和漫长的灰度,很多情况下尽管做了详细的测试灰度,也没法保证某一些用户或场景的 Corner Case 能被完全覆盖。
天下苦灰度久矣
针对单体应用,业界有成熟的金丝雀发布和蓝绿发布的解决方案,能帮助用户做更全面的灰度发布保障,但微服务场景下,往往多个微服务应用都在并行开发、测试、灰度,并且多个业务部分之间并没有直接交集,那就很可能出现某业务出现逻辑改动造成的非预期的影响,或是参数兼容问题,或是整个链路的性能影响。
比如图中所示的业务系统,如果 S1、S5、S7、S11 都发生了变更,其中 S7 服务的逻辑变更可能导致某些场景下请求时长变慢,如果事先没有进行全链路端到端的灰度验证,直接全量更新线上,很可能会影响到用户。
这种全链路端到端的灰度验证能力,是所有微服务系统都应当具备的,也是保证服务稳定性重要的一环。阿里双 11 每年都会进行全链路压测,保证所有业务逻辑端到端的功能和性能都能平稳应对双 11 的流量洪峰。正是这种全链路灰度的能力,让开发和运维人员从繁重和不可控的发布过程中解放出来,是实现持续交付的基础,也是安全生产的重要支撑。
SAE 全链路灰度解决方案
原理介绍
阿里云 Serverless 应用引擎(简称 SAE)通过集成 MSE 微服务治理能力,支持在 SAE 应用无缝使用全链路灰度功能。其中要怎么实现灰度环境的隔离是需要考虑的问题。常见的隔离方式分为物理隔离和逻辑隔离,
- 物理隔离: 这种方式会搭建一套独立的网络、计算资源环境去部署灰度的服务,常见于企业的测试开发环境,但对于线上灰度的环境,因为两套独立的环境很难完全保持一致,一般灰度环境和线上都会在同一套物理环境中。
物理隔离
- 逻辑隔离: 基于流量染色和分布式链路追踪技术,流量在微服务分布式环境中流转时,可以识别出灰度的流量,并且根据具体灰度规则做出动态流量路由。这种方式可以在线上环境逻辑隔离出灰度环境,并自动将满足条件的灰度流量引入灰度环境进行验证,帮助开发运维同学实时快速地对线上流量进行精细化全链路控制。
逻辑隔离
全链路灰度中的关键概念。
- 基线应用:在 SAE 生产环境中的应用,可以称作基线应用,当应用没有对应的灰度版本时,流量会默认路由到基线应用。
- 灰度应用:SAE 可以基于基线应用手动复制出一个灰度应用,它与基线应用在同一个命名空间,使用同一套应用配置(包括注册中心等),除了计算资源是新建出来的,其他都是复用的基线应用的。
- 灰度标签:灰度标签用于定义隔离的逻辑灰度环境,平台会自动识别应用的灰度标签,将具有同一灰度标签的应用都划分为同一分组。
- 泳道:基于灰度标签串联微服务调用链路的流量通道,同一灰度环境,需要设置不同灰度规则,就可以创建多个泳道。
- 泳道组:泳道的集合,一个泳道组下可以创建多个泳道。不同的泳道组对应不同的灰度环境,可以包含不同的灰度应用。泳道组的作用主要是为了区分不同团队或不同场景。
SAE 上的微服务全链路灰度基于逻辑隔离的原理,通过一键创建与生产环境配置一样的灰度应用,可快速支持用户构建起全链路的灰度场景。如下图所示,在命名空间 prod 下,我们可以搭建起线上灰度的链路,用于实际生产发布时候的灰度验证。而在命名空间 dev,我们也可以利用灰度应用的逻辑隔离能力,搭建多套开发环境,这样其实免去了搭建多个开发空间的资源浪费。
核心特性
SAE 下的全链路灰度围绕具体用户灰度痛点去针对性解决,具有以下核心特性:
- 全链路灰度支持多重灰度策略并行,满足多种业务灰度场景: 通过创建不同的泳道组,实现不同的灰度规则,比如通过比例灰度,可以将一定比例的流量引入灰度环境;而按内容灰度可以基于 HTTP 请求 Header、Cookie、Query、Body Content 等内容进行识别,如果满足灰度条件,则会将流量自动导入到灰度环境中。
- SAE 支持灰度应用的一键创建、启停能力,如果在非灰度状态,可以将灰度应用全部关停,需要再次灰度时,可以将灰度应用重启启动,这样无需用户单独创建灰度隔离环境,大幅降低机器/运维成本。
- 基于 Java Agent 技术无侵入式支持灰度流量感知与路由, 业务方不需要修改任何一行代码,即可在近 5 年的微服务框架 Spring Boot、Spring Cloud、Dubbo 上直接使用全链路灰度的能力。
- 全链路灰度和链路可观测相结合, 方便用户灰度过程中观测流量的具体分发情况,这对观察线上灰度情况直观重要。
操作实践
接下来我们介绍下在 SAE 上的使用全链路灰度的操作实践。
操作的链路架构图如下所示:其中调用链路是网关 -> A 应用 -> B 应用 -> C 应用。
步骤一:创建业务基线应用
在 SAE 控制台创建应用 A、B、C 和网关应用,这里用到的是 SpringCloud 网关。
步骤二:创建业务灰度应用
- 对每个 SAE 的基线应用开启为服务治理。进去应用概览-微服务治理,点击"开启微服务治理"。
- 基线应用开启微服务治理后,回到应用列表界面,创建灰度应用:
- 创建灰度应用的界面,这里灰度标签需要自定义:可以根据自己业务场景进行定义,这里比如设置为 g1。然后将灰度应用的镜像替换为您需要灰度发布的代码版本。
步骤三:创建灰度环境泳道组
- 回到 SAE 控制台的微服务治理-全链路灰度界面,点击创建泳道组,选择 Java 服务网关,泳道组流量入口选择您场景的网关应用,泳道组涉及应用选择需要包括到灰度环境中的应用。
- 在泳道组中创建泳道:点击创建第一个分流泳道,填写泳道信息,泳道标签可以选择之前选中到灰度环境中的应用所包含的标签。然后配置具体的灰度规则,根据业务具体逻辑,在 Path 处输入要灰度的请求路径。灰度模式可以选择按内容灰度或按流量比例灰度。如果选择内容灰度,还需要设置具体的灰度条件,即满足灰度条件的请求会被路由到灰度环境。
-
创建完泳道后,就可以发起请求,验证请求打到了灰度环境。如灰度规则所设置的,其中只有满足 Header 中包含 gray = gray 的请求才会落入灰度环境。
#测试命令 curl -H "gray:gray" 39.107.xxx.xxx:20000/A/a
#测试结果 Ag1[172.16.xx.xxx][config=base] -> 40ms -> B[172.16.xx.xxx] -> 17ms -> Cg1[172.16.xx.xxx]% ➜
- 如下图所示,可见灰度规则是生效的。我们进一步点开流量详细,可以看到灰度标上的流量数据,便于在实际线上进行灰度操作时观察灰度的走向。
SAE 微服务治理未来展望
SAE 通过与 MSE 进行深度集成,在 Serverless 场景下为用户提供了使用微服务治理能力的最短路径。全链路灰度作为其中的重磅功能,后续还将在更多的灰度发布能力场景化集成,流量可观测等方向为用户提供更完备的应用变更体验。此外,SAE 还提供无损上下线、限流降级等核心能力,为微服务应用运行稳定性保驾护航。
SAE 会继续致力于为用户提供极简易用、成本低廉、功能强大的 Serverless 应用全托管平台:"我们希望让用户做的更少而收获更多,通过 Serverless 化,深度用云就像用水电煤一样简单"。