微服务引擎 MSE(Microservices Engine)是火山引擎提供的一款面向微服务全生命周期的一站式微服务解决方案。产品提供开源增强的 Nacos 注册发现、配置管理,兼容原生 Spring Cloud 、gRPC 及 Service Mesh 架构丰富微服务治理能力。
来源 | 火山引擎云原生团队
在业务发布变更过程中,为最大限度降低对在线用户影响,保障版本发布质量,通常采用灰度发布的方式将少量的实际生产流量导入至更新版本,达到预期结果及充分测试验证后,将流量渐进式切流至更新版本随即完成基线版本服务下线。
然而在微服务架构体系中,由于服务间依赖关系错综复杂,单个功能模块发版需依赖上下游多个服务同时上线,需保障从网关流量入口开始到多个发版微服务间对特征版本充分验证的同时实现基准流量的业务闭环。
针对上述挑战,业界提出全链路灰度发布的实现方案,有效解决微服务架构多服务并行发布的流量隔离问题。在字节跳动内部,抖音、电商等多个业务域已将全链路灰度发布作为在线服务发布的标准规范并沉淀标准化工具,承载超过 30 万微服务、每周超 10 万次发布构建,有效提升了版本发布成功率,同时也帮助业务团队提前发现变更业务异常,降低发布变更失败业务损失。
要了解全链路灰度发布的实践过程,我们有必要先了解传统灰度发布背景、流程,分析在微服务架构体系下存在的问题。
步骤一:在生产环境设置指定资源池,该资源池与实际生产业务应用的基础资源保持一致(包括网络策略、数据库、中间件及第三方服务),屏蔽因资源环境差异导致发布变更异常;
步骤二:在指定资源池发布该服务的灰度实例;
步骤三:待灰度实例上线成功后,调整负载策略配置将少量实际生产流量路由至服务 A 的灰度节点;
步骤四:灰度版本验证成功后,逐步调整灰度版本流量比例或一次性切流至灰度版本;
与单个服务的灰度发布不同,微服务架构的发布过程更为复杂。举个例子,在一个业务领域存在 A、B、C、D 四个相互依赖的微服务共同构建闭环的业务逻辑,服务 A、B、C 之间采用标准 HTTP 协议通信,服务 C 和服务 D 通过消息中间件进行异步解耦。这 4 个服务涉及两个业务团队,服务 A、服务 C 归属团队 A ,在 feature_a 版本发布过程中存在相互依赖需要协同发布;服务 B、服务 D 归属团队 B,在 feature_B 版本发布过程中同样需要协同发布,且因归属不同团队且具有同样的发布窗口,存在并行发布场景。
如何解决上述复杂的全链路灰度发布问题,这里我们列举了一些对应落地的要点:
在流量入口需要能够识别 feature_a、feature_b 的流量特征,将流量匹配规则路由至下游服务对应的灰度版本,因此需要依赖于流量入口负载或网关的流量匹配、标识染色和流量路由能力。
feature_a 在服务 B、服务 D 没有对应特征版本(同理 feature_b 在服务 A、服务 C 也无对应特征版本),针对未匹配灰度规则的流量,需要将流量自动回流至基线版本,保障业务逻辑闭环。同时,在服务实例进程及线程切换过程中完成上下文串联。
服务 A、B、C 的单个服务实例根据接受的流量特征不同,需要匹配不同的流量路由规则,将其路由至下游指定的灰度版本。路由规则之间不相互影响,伴随灰度版本上线动态完成路由规则生效。
服务 C 和服务 D 通过异步消息事件进行解耦,在 HTTP 或 RPC 灰度流量经过消息投递时,需要将特征流量转化为特征消息事件完成流量标识在消息中间件的透传。
结合上述分析, 我们可以发现,传统基于单一入口负载灰度发布机制在微服务场景主要面临如下挑战:
无法实现相关业务域内多个服务灰度发布的流量闭环。由于服务调用涉及复杂调用关系,单个功能特性发布依赖相同业务域下多个微服务发布更新,需要将灰度流量精准调度在多个上下游依赖灰度服务实例,同时为保障整体业务闭环,允许灰度流量路由至服务的基线版本。要完成以上灰度流量的业务闭环,需在全链路服务调用过程中对灰度流量进行精准识别和路由控制。
无法提供具有特定业务规则的流量标识。在实际业务场景中,为进一步明确影响范围或基于业务规则对特征用户流量进行版本验证,通常需根据指定的用户 ID、地域、终端类型等特征业务标识对流量进行染色标记,将染色流量路由到指定的服务版本。因此,需要在流量入口能够基于业务语义精准识别特征流量,添加染色标识,并路由至下游服务的灰度版本。
无法满足多个特征版本并行发布场景。在一个大型产品体系下业务域复杂,将相同闭环的业务单元划分为相对独立的业务域,归属于不同的业务团队。在发布窗口有限的情况下,需要通过多个特性版本并行发布提升发布效率,然而不同的业务团队无法做到同步的发布感知,在并行发布过程中需要避免各业务团队的相互影响,使其在发布异常时能准确识别自身逻辑变更引发的异常问题。
经过上述剖析,结合业界及字节跳动内部实践,我们可以简单总结出微服务场景全链路灰度发布的设计原则:
提供流量逻辑隔离概念泳道。泳道涉及服务实例染色标记、流量匹配规则及发布依赖关联的一组服务。泳道内的服务实例仅接受染色标记流量,并优先将染色流量路由至下游匹配染色标记的目标实例;每个泳道流量相互独立,支持多个泳道并行生效,满足多产品特性并行上线验证需求。
在流量入口匹配业务规则对流量进行标记。需要将流量入口(入口网关、入口服务等)与泳道进行关联,匹配对应的染色规则和路由策略,将流量路由至对应泳道的服务实例,流量入口和泳道允许一对多关系。
泳道关联的路由及染色规则支持动态生效。与泳道关联的路由策略需伴随版本发布的切流动作动态下发至泳道内的所有服务实例并及时生效,通过泳道染色规则生效策略控制版本发布节奏。
提供基准泳道概念并生成默认的泳道规则:未匹配染色标记的流量将统一路由至基线泳道的服务实例。在泳道范围的灰度实例未上线时或未有匹配的流量路由规则时,允许流量自动回流至基线版本,保障业务的整体闭环。
火山引擎微服务引擎 MSE 的全链路灰度设计的核心原理包含 3 个要素:流量染色、实例打标、染色标记透传。
流量染色
主要在入口网关、入口服务等访问入口,对入口流量匹配业务规则的流量进行染色标记,在出口流量根据下游服务实例识别灰度标识,路由至对应泳道的服务。
微服务引擎 MSE 提供 2 种实现方式:针对 Spring Cloud Gateway 为代表的服务网关,可通过接入数据面自动获取识别染色规则增加标识及出口流量匹配;针对 Ingress 自建网关或云上托管 API 网关,可在网关手动设置路由规则将流量分流至下游灰度实例,进入灰度实例的流量将自动增加染色标识。
实例打标及流量路由
在创建泳道过程中,会生成泳道实例的染色标识并对泳道内服务下发指定的路由规则。当服务进行灰度发布时,需获取泳道标签对工作负载灰度实例进行染色标记;在服务实例启动后,数据面将拦截服务的注册发现行为将泳道元数据信息写入注册中心,通过同步任务将注册信息同步至 MSE 控制面,由其将路由及实例寻址信息更新至数据面,增强服务出口路由策略实现规则路由。
染色透传
微服务引擎 MSE 是火山引擎提供的一款面向微服务全生命周期的一站式微服务解决方案。产品提供开源增强的 Nacos 注册发现、配置管理的能力,兼容原生 Spring Cloud 、GRPC及 Service Mesh 架构丰富微服务治理能力,可以助力用户快速、便捷地构建微服务应用架构,解决中大型企业的微服务架构转型问题。
结合字节跳动内部业务积累的各种优秀实践,微服务引擎 MSE 在全链路灰度发布场景支持如下特性:
支持复杂业务流量匹配及流量隔离。通过泳道流量隔离逻辑,满足多个泳道设置不同的染色规则及路由隔离,通过 fallover 机制提供泳道严格及宽松模式的一键切换,支持多个业务团队并行发布相互解耦,避免彼此干扰,提升发布效率。
支持异构应用框架无侵入流量治理接入。提供 java agent 字节码增强及 sidecar 两种无侵入数据面接入方式,面向异构框架提供全链路灰度发布的流量染色、标识及流量路由的服务治理增强能力,降低应用接入推广成本。
与火山引擎云原生产品生态深度融合,闭环全链路灰度发布的流量调度。如联动火山引擎 API 网关支持入口流量染色、自动 header 路由匹配及后端服务实例的自动发现能力。
Demo 描述:存在 svc1、svc2、svc3 相互依赖的微服务,服务之间通过 Nacos 注册中心作为服务寻址,SCG 服务网关作为内部服务流量入口,内部服务通过 HTTP 协议调用正常联通情况下打印 service v1 → service v1 → service v1。
预期效果:根据灰度流量特征流量 x-canary:true 实现对该特征流量的全链路灰度发布, svc1 、svc2、svc3 均加入泳道列表,当下游服务未上线灰度实例,则将流量自动 fallback 至基线泳道。当存在 x-canary:true 流量接入后,打印 service v2 → service v2 → service v2。
步骤一:前置准备
已通过火山引擎 VKE 创建业务集群。业务集群用于部署 svc1 、svc2、svc3 工作负载;
已创建治理中心并纳管相关的业务集群。
步骤二:同步注册中心
完成导入注册中心并针对命名空间及 Group 创建同步任务,将服务注册信息同步至 MSE 管控面:
同步完成后,服务列表可查看已经从 Nacos 同步的服务信息,此时服务尚未接入数据面不具备流量治理能力:
步骤三:设置泳道规则
Fallback 策略:开启 fallback 后,针对泳道内未有染色标识的服务,流量将自动 fallback 至基线版本优先保障业务闭环;
服务列表:与版本发布特性相关的上下游依赖服务;
流量入口:流量入口支持基于 SCG 的服务网关以及非 MSE 管控体系的自建网关,如果是自建网关则手动配置路由策略将流量路由至服务的灰度实例,进入灰度实例的流量将自动添加对应的流量染色标记;
染色匹配规则:在 SCG 服务网关染色入口类型下,支持根据 HTTP 请求 header 规则匹配设置染色路由策略。
步骤四:服务治理接入
spec:
template:
metadata:
annotations:
sidecar.mesh.io/prestop-timeout: "5000"
labels:
sidecar.mesh.io/data-plane-mode: "java_proxy"
sidecar.mesh.io/lane: "lane-test"
sidecar.mesh.io/mse-namespace: "mse-demo-public-test"
服务网关 Annotations 和 Lables 注解:
spec:
template:
metadata:
labels:
service.istio.io/gateway-name: "gateway-test"
sidecar.mesh.io/data-plane-mode: "java_proxyless"
sidecar.mesh.io/mse-namespace: "mse-demo-public-test"
步骤五:生效泳道
步骤六:效果验证
基线版本:
灰度版本:增加特征流量 header,x-canary:true。
随着内外部客户的接入使用及深度体验,未来微服务引擎 MSE 在全链路灰度发布场景探索将聚焦于以下内容:
与云上及开源持续发布工具的无缝集成,实现资源发布与流量调度相匹配的渐进式发布。支持泳道流量规则 YAML 模板化配置,结合发布流水线的调度编排实现资源调度适应性的灰度比例分流,提升资源利用率及发布效率。
与云上观测产品集成,闭环全链路灰度发布的可观测性建设。支持泳道入口与内部服务的灰度流量指标观测及基于单笔请求灰度标识的全链路追踪,辅助发布变更的故障感知及边界定位,支撑有效、精准的切流管控策略实施。
欢迎感兴趣的用户扫码咨询、使用!
扫码咨询
火山引擎云原生团队主要负责火山引擎公有云及私有化场景中 PaaS 类产品体系的构建,结合字节跳动多年的云原生技术栈经验和最佳实践沉淀,帮助企业加速数字化转型和创新。产品包括容器服务、镜像仓库、分布式云原生平台、函数服务、服务网格、持续交付、可观测服务等。