作者:张海文,中国移动云能力中心高级软件研发工程师,移动云服务网格负责人,QCon、KubeCon等大会分享者,专注于云原生、微服务、算力网络等。
1概述
在当今快节奏的软件开发环境中,随着用户需求的不断变化和竞争日益激烈,软件更新和发布的频率已成为常态。然而,与此同时,保证用户体验的稳定性和可靠性也是至关重要的。传统的大规模软件发布往往会面临着线上故障风险,可能导致用户体验下降,甚至影响业务正常运行。
为了解决这一矛盾,在软件开发领域催生出了灰度发布的概念。灰度发布是一种渐进式的软件发布方式,它允许将新功能或更新逐步推送给一部分用户,而不是一次性全部发布。这样的方式能够有效降低线上故障的风险,保障用户体验,同时也为开发团队提供了更多时间和机会在全面发布前进行验证和修复。
然而,随着软件架构的演进,尤其是微服务架构的普及,软件系统往往由多个微服务组成,不同服务的版本升级需要协调和同步。在这种背景下,单一服务的灰度发布已经不能完全适应需求,全链路灰度发布应运而生。全链路灰度发布考虑到整个软件系统的多个微服务,允许多个微服务同时进行版本控制和升级,以确保整个系统的平稳过渡和稳定性,是一种更为全面和细致的灰度发布方式。通过全链路灰度发布,开发团队能够更加精确地控制不同服务版本的发布比例,降低系统风险,保障线上稳定性,最大程度地满足用户需求。
以图 1 为例,软件系统包含网关和 4 个微服务,通过全链路灰度发布,可以使ServiceB 和 ServiceD 进行灰度发布,通过灰线所示的流量进行灰度功能验证,同时不影响蓝线所示的正常访问流量。
2全链路灰度发布核心问题
我们通过图1 可以清晰地看到,在实施全链路灰度发布时,需要部署相关服务的灰度版本,并确保在整个请求的调用链上,网关和微服务组件能够准确识别正式流量和特定版本灰度流量,并根据流量类型动态地将请求路由到正确版本的上游微服务上。所以,我们需要解决以下几个问题:
-
微服务实例具有版本信息,针对不同流量对应版本实例提供服务; -
请求流量具有流量特征,可以区分出是请求不同版本微服务的流量; -
调用链上各组件可以根据流量特征将请求动态路由到正确版本的微服务上。 当前的微服务架构主要分为两类模式:一类是建立在传统微服务框架(例如Spring Cloud等)之上的微服务体系,另一类是云原生时代采用Kubernetes和服务网格(如Istio)构建的微服务架构,为了方便起见,我们姑且简称为传统模式和云原生模式。下面我们将介绍在两类模式下,如何解决以上问题,进行全链路灰度发布。
微服务标识
我们通过给微服务实例添加标识的方式,使微服务实例具有版本信息,针对不同流量对应版本实例提供服务。
传统模式
在传统模式下,一般需要产品根据使用的微服务框架决定添加标识的方式。我们以基于 Spring Cloud 框架 + Nacos注册中心 的微服务为例,一般通过在微服务元数据配置(spring.cloud.nacos.discovery.metadata)中添加标识,配置示例如下: