微服务全链路灰度方案介绍

目录

一、单体架构下的服务发布

1.1 蓝绿发布

二、微服务架构下的服务发布

三、微服务场景下服务发布的问题

四、全链路灰度解决方案

4.1 物理环境隔离

4.2 逻辑环境隔离

4.3 全链路灰度方案实现技术

4.3.1 标签路由

4.3.2 节点打标

4.3.3 流量染色

4.3.4 分布式链路追踪

4.3.4 逻辑环境隔离

4.4 MSE微服务治理全链路灰度

4.4.1 MSE 服务治理特性

4.4.1.1 可通过定制规则引⼊精细化流量

4.4.1.2 全链路隔离流量泳道

4.4.1.3 端到端的稳定基线环境

4.4.1.4 流量⼀键动态切流

4.4.1.5 低成本接⼊,基于 Java Agent 技术实现⽆需修改⼀⾏业务代码

4.4.1.6 具备⽆损上下线能⼒,使得发布更加丝滑

4.4.2 RPC流量的全链路灰度⽅案


一、单体架构下的服务发布

⾸先,我们先看⼀下在单体架构中,如何对应⽤中某个服务模块进⾏新版本发布。如下图,应⽤中的 Cart 服务模块有新版本迭代:

由于 Cart 服务是应⽤的⼀部分,所以新版本上线时需要对整个应⽤进⾏编译、打包以及部署。服务级别发布问题变成了应⽤级别的发布问题,我们需要对应⽤的新版本⽽不是服务来实施有效的发布策略。

1.1 蓝绿发布

⽬前,业界已经有⾮常成熟的服务发布⽅案,例如蓝绿发布和灰度发布。蓝绿发布需要对服务的新版本进⾏冗余部署,⼀般新版本的机器规格和数量与旧版本保持⼀致,相当于该服务有两套完全相同的部署环境,只不过此时只有旧版本在对外提供服务,新版本作为热备。当服务进⾏版本升级时,我们只需将流量全部切换到新版本即可,旧版本作为热备。我们的例⼦使⽤蓝绿发布的示意图如下,流量切换基于四层代理的流量⽹关即可完成。

在蓝绿发布中,由于存在流量整体切换,所以需要按照原服务占⽤的机器规模为新版本克隆⼀套环境,相当于要求原来 1 倍的机器资源。灰度发布的核⼼思想是根据请求内容或者请求流量的⽐例将线上流量的⼀⼩部分转发⾄新版本,待灰度验证通过后,逐步调⼤新版本的请求流量,是⼀种循序渐进的发布⽅式。我们的例⼦使⽤灰度发布的示意图如下,基于内容或⽐例的流量控制需要借助于⼀个七层代理的微服务⽹关来完成。

其中,Traffic Routing 是基于内容的灰度⽅式,⽐如请求中含有头部 stag=gray 的流量路由到应⽤v2 版本;Traffic Shifting 是基于⽐例的灰度⽅式,以⽆差别的⽅式对线上流量按⽐重进⾏分流。相⽐蓝绿发布,灰度发布在机器资源成本以及流量控制能⼒上更胜⼀筹,但缺点就是发布周期过⻓,对运维基础设施要求较⾼。

二、微服务架构下的服务发布

在分布式微服务架构中,应⽤中被拆分出来的⼦服务都是独⽴部署、运⾏和迭代的。单个服务新版本上线时,我们再也不需要对应⽤整体进⾏发版,只需关注每个微服务⾃身的发布流程即可,如下:

为了验证服务 Cart 的新版本,流量在整个调⽤链路上能够通过某种⽅式有选择的路由到 Cart的灰度版本,这属于微服务治理领域中流量治理问题。常⻅的治理策略包括基于 Provider 和基于 Consumer 的⽅式。

  • 基于 Provider 的治理策略。配置 Cart 的流量流⼊规则,User 路由到 Cart 时使⽤Cart 的流量流⼊规则。
  • 基于 Consumer 的治理策略。配置 User 的流量流出规则, User 路由到 Cart 时使⽤User 的流量流出规则。

此外,使⽤这些治理策略时可以结合上⾯介绍的蓝绿发布和灰度发布⽅案来实施真正的服务级别的版本发布。

三、微服务场景下服务发布的问题

继续考虑上⾯微服务体系中对服务 Cart 进⾏发布的场景,如果此时服务 Order 也需要发布新版本,由于本次新功能涉及到服务 Cart 和 Order 的共同变动,所以要求在灰度验证时能够使得灰度流量同时经过服务 Cart 和 Order 的灰度版本。如下图:

按照上⼀⼩节提出的两种治理策略,我们需要额外配置服务 Order 的治理规则,确保来⾃灰度环境的服务 Cart 的流量转发⾄服务 Order 的灰度版本。这样的做法看似符合正常的操作逻辑,但在真实业务场景中,业务的微服务规模和数量远超我们的例⼦,其中⼀条请求链路可能经过数⼗个微服务,新功能发布时也可能会涉及到多个微服务同时变更,并且业务的服务之间依赖错综复杂,频繁的服务发布、以及服务多版本并⾏开发导致流量治理规则⽇益膨胀,给整个系统的维护性和稳定性带来了不利因素。

四、全链路灰度解决方案

对于以上的问题,开发者结合实际业务场景和⽣产实践经验,提出了⼀种端到端的灰度发布⽅案,即全链路灰度。全链路灰度治理策略主要专注于整个调⽤链,它不关⼼链路上经过具体哪些微服务,流量控制视⻆从服务转移⾄请求链路上,仅需要少量的治理规则即可构建出从⽹关到整个后端服务的多个流量隔离环境,有效保证了多个亲密关系的服务顺利安全发布以及服务多版本并⾏开发,进⼀步促进业务的快速发展。

如何在实际业务场景中去快速落地全链路灰度呢?⽬前,主要有两种解决思路,基于物理环境隔离和基于逻辑环境隔离。

4.1 物理环境隔离

物理环境隔离,顾名思义,通过增加机器的⽅式来搭建真正意义上的流量隔离。

这种⽅案需要为要灰度的服务搭建⼀套⽹络隔离、资源独⽴的环境,在其中部署服务的灰度版本。由于与正式环境隔离,正式环境中的其他服务⽆法访问到需要灰度的服务,所以需要在灰度环境中冗余部署这些线上服务,以便整个调⽤链路正常进⾏流量转发。此外,注册中⼼等⼀些其他依赖的中间件组件也 需要冗余部署在灰度环境中,保证微服务之间的可⻅性问题,确保获取的节点 IP 地址只属于当前的⽹络环境。

这个⽅案⼀般⽤于企业的测试、预发开发环境的搭建,对于线上灰度发布引流的场景来说其灵活性不够。况且,微服务多版本的存在在微服务架构中是家常便饭,需要为这些业务场景采⽤堆机器的⽅式来 维护多套灰度环境。如果您的应⽤数⽬过多的情况下,会造成运维、机器成本过⼤,成本和代价远超收益;如果应⽤数⽬很⼩,就两三个应⽤,这个⽅式还是很⽅便的,可Microservice 以接受的。

4.2 逻辑环境隔离

另⼀种⽅案是构建逻辑上的环境隔离,我们只需部署服务的灰度版本,流量在调⽤链路上流转时,由流经的⽹关、各个中间件以及各个微服务来识别灰度流量,并动态转发⾄对应服务的灰度版本。如下图:

上图可以很好展示这种方案的效果,我们用不同的颜色来表示不同版本的灰度流量,可以看出无论是微服务网关还是微服务本身都需要识别流量,根据治理规则做出动态决策。当服务版本发生变化时,这个调用链路的转发也会实时改变。相比于利用机器搭建的灰度环境,这种方案不仅可以节省大量的机器成本和运维人力,而且可以帮助开发者实时快速的对线上流量进行精细化的全链路控制。


那么全链路灰度具体是如何实现呢?通过上⾯的讨论,我们需要解决以下问题:


1.链路上各个组件和服务能够根据请求流量特征进⾏动态路由。
2.需要对服务下的所有节点进⾏分组,能够区分版本。
3.需要对流量进⾏灰度标识、版本标识。
4.需要识别出不同版本的灰度流量。


接下来,会介绍解决上述问题需要⽤到的技术

4.3 全链路灰度方案实现技术

4.3.1 标签路由

标签路由通过对服务下所有节点按照标签名和标签值不同进⾏分组,使得订阅该服务节点信息的服务消费端可以按需访问该服务的某个分组,即所有节点的⼀个⼦集。服务消费端可以使⽤服务提供者节点上的任何标签信息,根据所选标签的实际含义,消费端可以将标签路由应⽤到更多的业务场景中。

4.3.2 节点打标

那么如何给服务节点添加不同的标签呢?在如今⽕热的云原⽣技术推动下,⼤多数业务都在积极进⾏容器化改造之旅。这⾥,我就以容器化的应⽤为例,介绍在使⽤Kubernetes Service 作为服务发现和使⽤⽐较流⾏的Nacos 注册中⼼这两种场景下如何对服务 Workload 进⾏节点打标。


在使⽤Kubernetes Service 作为服务发现的业务系统中,服务提供者通过向 ApiServer 提交Service 资源完成服务暴露,服务消费端监听与该 Service 资源下关联的 Endpoint 资源,从Endpoint 资源中获取关联的业务 Pod 资源,读取上⾯的 Labels 数据并作为该节点的元数据信息。所以,我们只要在业务应⽤描述资源 Deployment 中的 Pod 模板中为节点添加标签即可。

在使⽤Nacos 作为服务发现的业务系统中,⼀般是需要业务根据其使⽤的微服务框架来决定打标⽅式。 如果 Java 应⽤使⽤的 Spring Cloud 微服务开发框架,我们可以为业务容器添加对应的环境变量来完成标签的添加操作。⽐如我们希望为节点添加版本灰度标,那么为业务容器添加 `spring.cloud.nacos.discovery.metadata.version=gray`,这样框架向 Nacos 注册该节点时会为其添加⼀个标签 `verison=gray`。

4.3.3 流量染色

请求链路上各个组件如何识别出不同的灰度流量?答案就是流量染⾊,为请求流量添加不同灰度标识来⽅便区分。我们可以在请求的源头上对流量进⾏染⾊,前端在发起请求时根据⽤户信息或者平台信息的不同对流量进⾏打标。如果前端⽆法做到,我们也可以在微服务⽹关上对匹配特定路由规则的请求动态 添加流量标识。此外,流量在链路中流经灰度节点时,如果请求信息中不含有灰度标识,需要⾃动为其染⾊,接下来流量就可以在后续的流转过程中优先访问服务的灰度版本。

4.3.4 分布式链路追踪

还有⼀个很重要的问题是如何保证灰度标识能够在链路中⼀直传递下去呢?如果在请求源头染⾊,那么请求经过⽹关时,⽹关作为代理会将请求原封不动的转发给⼊⼝服务,除⾮开发者在⽹关的路由策略中实施请求内容修改策略。接着,请求流量会从⼊⼝服务开始调⽤下⼀个微服务,会根据业务代码逻辑形成新的调⽤请求,那么我们如何将灰度标识添加到这个新的调⽤请求,从⽽可以在链路中传递下去呢?

从单体架构演进到分布式微服务架构,服务之间调⽤从同⼀个线程中⽅法调⽤变为从本地进程的服务调⽤远端进程中服务,并且远端服务可能以多副本形式部署,以⾄于⼀条请求流经的节点是不可预知的、不确定的,⽽且其中每⼀跳的调⽤都有可能因为⽹络故障或服务故障⽽出错。分布式链路追踪技术对⼤型分布式系统中请求调⽤链路进⾏详细记录,核⼼思想就是通过⼀个全局唯⼀的 traceid 和每⼀条的 spanid 来记录请求链路所经过的节点以及请求耗时,其中traceid 是需要整个链路传递的。

借助于分布式链路追踪思想,我们也可以传递⼀些⾃定义信息,⽐如灰度标识。业界常⻅的分布式链路追踪产品都⽀持链路传递⽤户⾃定义的数据,其数据处理流程如下图所示:

4.3.4 逻辑环境隔离

⾸先,需要⽀持动态路由功能,对于 Spring Cloud、Dubbo 开发框架,可以对出⼝流量实现⾃定义 Filter,在该 Filter 中完成流量识别以及标签路由。同时需要借助分布式链路追踪技术完成流量识别以及标签路由。同时需要借助分布式链路追踪技术完成流量标识链路传递以及流量⾃动染⾊。此外,需要引⼊⼀个中⼼化的流量治理平台,⽅便各个业务线的开发者定义⾃⼰的全链路灰度规则。如下图所示:

实现全链路灰度的能⼒,⽆论是成本还是技术复杂度都是⽐较⾼的,以及后期的维护、扩展都是⾮常⼤的成本。

如果我们不想自己维护,且考虑后期成本问题,那么,我们可以选择使用阿里的MSE微服务治理全链路灰度方案。下面我们来看下MSE产品提供的方案。

4.4 MSE微服务治理全链路灰度

阿⾥云 MSE 服务治理产品,该产品就是⼀款基于 Java Agent 实现的⽆侵⼊式企业⽣产级服务治理产品,您不需要修改任何⼀⾏业务代码,即可拥有不限于全链路灰度的治理能⼒,并且⽀持近 5 年内所有的 Spring Boot、Spring Cloud 和 Dubbo。

4.4.1 MSE 服务治理特性

全链路灰度作为 MSE 服务治理专业版中的拳头功能,具备以下六⼤特点:

4.4.1.1 可通过定制规则引⼊精细化流量

除了简单地按照⽐例进⾏流量引⼊外,我们还⽀持 Spring Cloud 与 Dubbo 流量按规则引⼊,Spring Cloud 流量可根据请求的 cookie、header、param 参数或随机百分⽐引⼊流量,Dubbo 流量可按照服务、⽅法、参数来引⼊。

4.4.1.2 全链路隔离流量泳道

1)通过设置流量规则对所需流量进⾏'染⾊','染⾊'流量会路由到灰度机器。
2)灰度流量携带灰度标往下游传递,形成灰度专属环境流量泳道,⽆灰度环境应⽤会默认选择未打标的基线环境。

4.4.1.3 端到端的稳定基线环境

未打标的应⽤属于基线稳定版本的应⽤,即稳定的线上环境。当我们将发布对应的灰度版本代码,然后可以配置规则定向引⼊特定的线上流量,控制灰度代码的⻛险。

4.4.1.4 流量⼀键动态切流

流量规则定制后,可根据需求进⾏⼀键停启,增删改查,实时⽣效。灰度引流更便捷。

4.4.1.5 低成本接⼊,基于 Java Agent 技术实现⽆需修改⼀⾏业务代码

MSE 微服务治理能⼒基于 Java Agent 字节码增强的技术实现,⽆缝⽀持市⾯上近 5 年的所有Spring Cloud 和 Dubbo 的版本,⽤户不⽤改⼀⾏代码就可以使⽤,不需要改变业务的现有架构,随时可上可下,没有绑定。只需开启 MSE 微服务治理专业版,在线配置,实时⽣效。

4.4.1.6 具备⽆损上下线能⼒,使得发布更加丝滑

应⽤开启MSE服务治理后就具备⽆损上下线能⼒,⼤流量下的发布、回滚、扩容、缩容等场景,均能保证流量⽆损。

4.4.2 RPC流量的全链路灰度⽅案

基于消息队列 RocketMQ 的全链路灰度⽅案

详细可以了解 MSE 服务治理的帮助⽂档 :

MSE基于消息队列RocketMQ版实现全链路灰度_微服务引擎(MSE)-阿里云帮助中心 (aliyun.com)

MSE 服务治理以⽆侵⼊的⽅式提供了全链路灰度、离群实例摘除、⾦丝雀发布、微服务治理流量可观测等核⼼能⼒,以更经济的⽅式、更⾼效的路径帮助我们的系统在云上快速构建起完整微服务治理体系。中小企业可选择该中方式实现全链路灰度方案。

友情连接:如果你对发布稳定性的相关方案内容也感兴趣,可查看本人博客文章线上发布稳定性方案介绍-CSDN博客

好了,本次分享就到这里,如果帮助到大家,欢迎大家点赞+关注+收藏,有疑问也欢迎大家评论留言!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/231550.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis源码分析(二):项目结构

目录 1、前言 2、代码统计 3、整体架构 3.1、基础支持层 3.1.1、反射模块 3.1.2、类型模块 3.1.3、日志模块 3.1.4、IO模块 3.1.5、解析器模块 3.1.6、数据源模块 3.1.7、缓存模块 3.1.8、Binding 模块 3.1.9、注解模块 3.1.10、异常模块 3.2、核心处理层 3.2.…

Pytorch简介

1.1 Pytorch的历史 PyTorch是一个由Facebook的人工智能研究团队开发的开源深度学习框架。在2016年发布后,PyTorch很快就因其易用性、灵活性和强大的功能而在科研社区中广受欢迎。下面我们将详细介绍PyTorch的发展历程。 在2016年,Facebook的AI研究团队…

【C++】Ubuntu编译filezilla client

在新版Ubuntu 22.04.3 LTS上编译filezilla client成功,shell命令如下: sudo apt-get install libfilezilla-dev libwxbase3.0-dev gnutls-dev libdbus-1-dev sudo apt-get install libwxgtk3.0-gtk3-dev sudo apt-get install libgtk-3-dev sudo apt-ge…

【GO语言卵细胞级别教程】01.GO基础知识

01.GO基础知识 目录 01.GO基础知识1.GO语言的发展历程2.发展历程3.Windowns安装4.VSCode配置5.基础语法5.1 第一段代码5.2 GO执行的流程5.3 语法规则5.4 代码风格5.5 学习网址 1.GO语言的发展历程 Go语言是谷歌公司于2007年开始开发的一种编程语言,由Robert Griese…

Python从入门到精通之元类

系列 Python从入门到精通之安装与快速入门-CSDN博客 Python从入门到精通之基本数据类型和变量-CSDN博客 Python从入门到精通之集合(List列表、Tuple元组、Dict字典、Set)-CSDN博客 Python从入门到精通之条件语句、循环语句和函数-CSDN博客 Python从…

STM32疑难杂症

1.keil的奇怪问题 创建的数组分配内存到0x10000000地址的时候,数据总是莫名其妙的出现问题,取消勾选就正常了 stm32f407内部有一个CCM内存,这部分内存只能由内核控制,任何外设都不能够进行访问。这样问题就来了,如果使…

ES6 class详解

✨ 专栏介绍 在现代Web开发中,JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性,还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言,JavaScript具有广泛的应用场景&#x…

基于SSM框架的宠物商城系统

开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 功能模块&…

基于引力搜索算法优化的Elman神经网络数据预测 - 附代码

基于引力搜索算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于引力搜索算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于引力搜索优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&…

(leetcode)判断字符是否唯一 -- 使用位图(位运算)

个人主页:Lei宝啊 愿所有美好如期而遇 目录 本题链接 输入描述 输出描述 算法分析 算法一:哈希表 算法二:位运算(位图) 解题源码 本题链接 力扣(LeetCode) 输入描述 接口:bool isUnique(st…

【AIGC风格prompt】风格类绘画风格的提示词技巧

风格类绘画风格的提示词展示 主题:首先需要确定绘画的主题,例如动物、自然景观、人物等。 描述:根据主题提供详细的描述,包括颜色、情感、场景等。 绘画细节:描述绘画中的细节,例如表情、纹理、光影等。 场…

分布式(7)

目录 31.基于Zookeeper如何实现分布式锁? 32.什么是ACID? 33.什么是分布式的XA协议? 34.什么是2PC? 35.什么是3PC? 31.基于Zookeeper如何实现分布式锁? 顺序节点 创建一个用于发号的节点“/test/lock…

Go语言学习

运行和解析 go run 命令已包含了编译和运行。它会先在一个临时目录编译程序,然后执行完后清理掉. 如果在run的后面加上 --work参数来查看临时目录。go run --work main.go也可以通过go build命令来编译代码,执行后会生成一个可以执行文件,通…

商家如何通过会员充值消费管理系统提升业务运营与用户体验

在当今数字化商业环境中,会员充值消费管理系统已经成为各类商家提高客户粘性、优化服务流程、增强市场竞争力的重要工具。那么如何通过会员充值消费管理系统提升业务运营与用户体验,商家是否有所了解呢?下面就带大家简单了解。 首先&#xf…

[每周一更]-(第50期):Go的垃圾回收GC

参考文章: https://juejin.cn/post/7111515970669117447https://draveness.me/golang/docs/part3-runtime/ch07-memory/golang-garbage-collector/https://colobu.com/2022/07/16/A-Guide-to-the-Go-Garbage-Collector/https://liangyaopei.github.io/2021/01/02/g…

【深度学习每日小知识】数据增强

数据增强是通过对原始数据进行各种转换和修改来人工生成附加数据的过程,旨在增加机器学习模型中训练数据的大小和多样性。这对于计算机视觉领域尤为重要,因为图像经常被用作输入数据。 计算机视觉中的数据增强 数据增强的主要目标是解决过拟合问题&…

数据库的学习笔记——第一篇

SQL通用语法 SQL语句 DDL 数据定义 数据库、表字段 DML 数据操作 增删改 DQL 数据查询 查询表中记录 DCL 数据控制 创建用户、控制用户权限 DLL语句——数据库操作 SHOW DATABASES; # 查询数据库SELECT DATABASE(); # 查询当前数据库CREATE DATABASE [IF …

【C语言】函数

函数是什么? “函数”是我们早些年在学习数学的过程中常见的概念,简单回顾一下:比如下图中,你给函数 f(x)2*x3 一个具体的x,这个函数通过一系列的计算来返回给你一个结果(图示如下)。 这就是数学中函数的基本过程和作用。但是你…

Python实现PowerPoint(PPT/PPTX)到PDF的批量转换

演示文稿是一种常见传达信息、展示观点和分享内容的形式,特别是PowerPoint演示文稿,广泛应用于各行各业,几乎是演讲等场合的必备工具。然而,演示文稿也有其限制,对设备的要求较高,且使用不同的软件或设备演…

PyTorch 入门学习数据操作之创建

简介 在深度学习中,我们通常会频繁地对数据进行操作;要操作一般就需要先创建。 官方介绍 The torch package contains data structures for multi-dimensional tensors and defines mathematical operations over these tensors. Additionally, it pr…