作者:扬少
当服务有新版本要公布上线时,通过引流一小部分流量到新版本,能够及时发现程序问题,无效阻止大面积故障的产生。业界上曾经有比拟成熟的服务公布策略,比方蓝绿公布、A/B 测试以及金丝雀公布,这些公布策略次要专一于如何对单个服务进行公布。在微服务体系架构中,服务之间的依赖关系盘根错节,有时某个性能发版依赖多个服务同时降级上线。咱们心愿能够对这些服务的新版本同时进行小流量灰度验证,这就是微服务架构中特有的全链路灰度场景,通过构建从网关到整个后端服务的环境隔离来对多个不同版本的服务进行灰度验证。
本文将会揭开全链路灰度的神秘面纱,深刻分析全链路灰度技术底细,引出两种不同的实现计划,并对实现计划的技术细节进行深入探讨,最初通过实际环节来展现全链路灰度在理论业务中的应用场景。
微服务架构带来的挑战
为了满足业务的迭代速度,开发者开始对原来的单体架构进行细粒度的拆分,将单体利用中的服务模块拆分成一个个独立部署运行的微服务,并且这些微服务的生命周期由对应的业务团队单独负责,无效的解决了单体架构中存在的敏捷性有余、灵活性不强的问题。常见的做法是依据业务域或者功能域进行服务拆分,如下图:
其中,流量网关是四层代理,次要性能有负载平衡、TLS 卸载以及一些平安防护性能;微服务网关是七层代理,次要用来裸露后端服务、流量治理、访问控制和流量监控。以 ” 高内聚、低耦合 ” 作为设计理念的微服务架构为开发者带来了前所未有的开发体验,每个业务团队专一于本身业务的代码逻辑,并通过 API 模式对外公布。服务依赖方只需引入服务提供方的 API 定义,即可实现服务之间通信,无需关怀服务提供方的部署状态和外部实现。
但任何架构都不是银弹,在解决旧问题同时势必会引入一些新的问题。微服务体系中最令人头疼的问题,是如何对泛滥微服务进行高效、便捷的治理,次要体现在可见性、连接性和安全性这三个方面。进一步细化,微服务架构带来了以下的挑战:
本文的重点次要关注服务公布这一子畛域,如何保障微服务体系中服务新版本升级过程中平滑无损,以及如何低成本的为多个微服务构建流量隔离环境,不便开发者同时对多个服务新版本进行充沛的灰度验证,防止故障的产生。
什么是全链路灰度
单体架构下的服务公布
首先,咱们先看一下在单体架构中,如何对利用中某个服务模块进行新版本公布。如下图,利用中的 Cart 服务模块有新版本迭代:
因为 Cart 服务是利用的一部分,所以新版本上线时须要对整个利用进行编译、打包以及部署。服务级别公布问题变成了利用级别的公布问题,咱们须要对利用的新版本而不是服务来施行无效的公布策略。
目前,业界曾经有十分成熟的服务公布计划,例如蓝绿公布和灰度公布。蓝绿公布须要对服务的新版本进行冗余部署,个别新版本的机器规格和数量与旧版本保持一致,相当于该服务有两套完全相同的部署环境,只不过此时只有旧版本在对外提供服务,新版本作为热备。当服务进行版本升级时,咱们只需将流量全副切换到新版本即可,旧版本作为热备。咱们的例子应用蓝绿公布的示意图如下,流量切换基于四层代理的流量网关即可实现。
在蓝绿公布中,因为存在流量整体切换,所以须要依照原服务占用的机器规模为新版本克隆一套环境,相当于要求原来 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 的灰度版本。这样的做法看似合乎失常的操作逻辑,但在实在业务场景中,业务的微服务规模和数量远超咱们的例子,其中一条申请链路可能通过数十个微服务,新性能公布时也可能会波及到多个微服务同时变更,并且业务的服务之间依赖盘根错节,频繁的服务公布、以及服务多版本并行开发导致流量治理规定日益收缩,给整个零碎的维护性和稳定性带来了不利因素。
对于以上的问题,开发者结合实际业务场景和生产实践经验,提出了 一种端到端的灰度公布计划,即全链路灰度。全链路灰度治理策略次要专一于整个调用链,它不关怀链路上通过具体哪些微服务,流量管制视角从服务转移至申请链路上,仅须要大量的治理规定即可构建出从网关到整个后端服务的多个流量隔离环境,无效保障了多个亲密关系的服务顺利平安公布以及服务多版本并行开发,进一步促成业务的疾速倒退。
全链路灰度的解决方案
如何在理论业务场景中去疾速落地全链路灰度呢?目前,次要有两种解决思路,基于物理环境隔离和基于逻辑环境隔离。
物理环境隔离
物理环境隔离,顾名思义,通过减少机器的形式来搭建真正意义上的流量隔离。
这种计划须要为要灰度的服务搭建一套网络隔离、资源独立的环境,在其中部署服务的灰度版本。因为与正式环境隔离,正式环境中的其余服务无法访问到须要灰度的服务,所以须要在灰度环境中冗余部署这些线上服务,以便整个调用链路失常进行流量转发。此外,注册核心等一些其余依赖的中间件组件也须要冗余部署在灰度环境中,保障微服务之间的可见性问题,确保获取的节点 IP 地址只属于以后的网络环境。
这个计划个别用于企业的测试、预发开发环境的搭建,对于线上灰度公布引流的场景来说其灵活性不够。况且,微服务多版本的存在在微服务架构中是粗茶淡饭,须要为这些业务场景采纳堆机器的形式来保护多套灰度环境。如果您的利用数目过多的状况下,会造成运维、机器老本过大,老本和代价远超收益;如果利用数目很小,就两三个利用,这个形式还是很不便的,能够承受的。
逻辑环境隔离
另一种计划是构建逻辑上的环境隔离,咱们只需部署服务的灰度版本,流量在调用链路上流转时,由流经的网关、各个中间件以及各个微服务来辨认灰度流量,并动静转发至对应服务的灰度版本。如下图:
上图能够很好展现这种计划的成果,咱们用不同的色彩来示意不同版本的灰度流量,能够看出无论是微服务网关还是微服务自身都须要辨认流量,依据治理规定做出动静决策。当服务版本发生变化时,这个调用链路的转发也会实时扭转。相比于利用机器搭建的灰度环境,这种计划不仅能够节俭大量的机器老本和运维人力,而且能够帮忙开发者实时疾速的对线上流量进行精细化的全链路管制。
那么全链路灰度具体是如何实现呢?通过下面的探讨,咱们须要解决以下问题:
- 链路上各个组件和服务可能依据申请流量特色进行动静路由
- 须要对服务下的所有节点进行分组,可能辨别版本
- 须要对流量进行灰度标识、版本标识
- 须要辨认出不同版本的灰度流量
接下来,会介绍解决上述问题须要用到的技术。
标签路由
标签路由通过对服务下所有节点依照标签名和标签值不同进行分组,使得订阅该服务节点信息的服务生产端能够按需拜访该服务的某个分组,即所有节点的一个子集。服务生产端能够应用服务提供者节点上的任何标签信息,依据所选标签的理论含意,生产端能够将标签路由利用到更多的业务场景中。
节点打标
那么如何给服务节点增加不同的标签呢?在现在炽热的云原生技术推动下,大多数业务都在踊跃进行容器化革新之旅。这里,我就以容器化的利用为例,介绍在应用 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
。
流量染色
申请链路上各个组件如何辨认出不同的灰度流量?答案就是流量染色,为申请流量增加不同灰度标识来不便辨别。咱们能够在申请的源头上对流量进行染色,前端在发动申请时依据用户信息或者平台信息的不同对流量进行打标。如果前端无奈做到,咱们也能够在微服务网关上对匹配特定路由规定的申请动静增加流量标识。此外,流量在链路中流经灰度节点时,如果申请信息中不含有灰度标识,须要主动为其染色,接下来流量就能够在后续的流转过程中优先拜访服务的灰度版本。
分布式链路追踪
还有一个很重要的问题是如何保障灰度标识可能在链路中始终传递上来呢?如果在申请源头染色,那么申请通过网关时,网关作为代理会将申请一成不变的转发给入口服务,除非开发者在网关的路由策略中施行申请内容批改策略。接着,申请流量会从入口服务开始调用下一个微服务,会依据业务代码逻辑造成新的调用申请,那么咱们如何将灰度标识增加到这个新的调用申请,从而能够在链路中传递上来呢?
从单体架构演进到散布式微服务架构,服务之间调用从同一个线程中办法调用变为从本地过程的服务调用远端过程中服务,并且远端服务可能以多正本模式部署,以至于一条申请流经的节点是不可预知的、不确定的,而且其中每一跳的调用都有可能因为网络故障或服务故障而出错。分布式链路追踪技术对大型分布式系统中申请调用链路进行具体记录,核心思想就是通过一个全局惟一的 traceid 和每一条的 spanid 来记录申请链路所通过的节点以及申请耗时,其中 traceid 是须要整个链路传递的。
借助于分布式链路追踪思维,咱们也能够传递一些自定义信息,比方灰度标识。业界常见的分布式链路追踪产品都反对链路传递用户自定义的数据,其数据处理流程如下图所示:
逻辑环境隔离——基于 SDK
下面咱们具体介绍了实现全链路灰度所须要的几种技术,如果想为现有的业务接入全链路灰度能力,不可避免的须要为业务应用的开发框架 SDK 进行革新。首先,须要反对动静路由性能,对于 Spring Cloud、Dubbo 开发框架,能够对进口流量实现自定义 Filter,在该 Filter 中实现流量辨认以及标签路由。同时须要借助分布式链路追踪技术实现流量标识链路传递以及流量主动染色。此外,须要引入一个中心化的流量治理平台,不便各个业务线的开发者定义本人的全链路灰度规定。基于 SDK 实现形式的图例如下:
逻辑环境隔离——基于 Java Agent
基于 SDK 形式的弊病在于须要业务进行 SDK 版本升级,甚至会波及到业务代码的变动。企业外部各个微服务尽管应用同一种开发框架,但很难保障框架版本是统一的,所以不得不为每一个版本保护一份全链路灰度的代码。业务代码与 SDK 代码紧耦合,SDK 版本迭代会触发业务不必要的发版变更,对业务的侵入性比拟强。
另一种比拟风行的形式是基于字节码加强技术在编译时对开发框架进行性能拓展,这种计划业务无感知,以无侵入形式为业务引入全链路灰度能力。基于 Java Agent 的实现形式的图例如下:
但依然无奈防止是开发者须要为业务应用版本不统一的开发框架保护对应的 Java Agent 的版本。如果您比拟偏向于这种无侵入的计划但又不想本人来保护,您能够抉择阿里云 MSE 服务治理产品,该产品就是一款基于 Java Agent 实现的无侵入式企业生产级服务治理产品,您不须要批改任何一行业务代码,即可领有不限于全链路灰度的治理能力,并且反对近 5 年内所有的 Spring Boot、Spring Cloud 和 Dubbo。
逻辑环境隔离——基于 Service Mesh
在业务零碎的微服务架构中,如果存在大量应用不同的技术栈、语言栈的微服务,Java Agent 的形式就无能为力了。咱们可能须要为每一个语言的 SDK 编写和保护全链路灰度代码,不仅须要不同语言栈的开发者,而且波及到语言无关的 bug 修复时须要全语言版本的 SDK 独特降级,这种代价不见得比基于物理环境隔离计划小。
那有没有一种与语言无关的计划呢?有,下一代微服务架构服务网格,Service Mesh。它将分布式服务的通信层形象为独自的一层,在这一层中实现负载平衡、服务发现、认证受权、监控追踪、流量管制等分布式系统所须要的性能。显然,咱们所需的全链路灰度能力也能够在这个流量治理基础设施层来实现。侥幸的是,服务网格明星产品 Istio 以申明式 API 资源对流量治理进行了对立形象,借助于 VirtualService 和 DestinationRule 治理规定能够很容易实现全链路灰度的成果,并且 Istio 集成了各种支流的分布式链路追踪框架。基于 Service Mesh 的实现形式的图例如下:
在理论生产环境中,服务多版本并行开发是很常见的事件,而且版本迭代速度十分快。版本每次变更都须要批改 VirtualSerivice 资源中路由匹配规定,另外 VirtualSerivice 资源中并没有提供容灾能力。比方存在一条路由规定拜访服务提供方的某个灰度版本,如果指标服务不存在该灰度版本或者不可用,依照目前 Istio 的实现是依然将流量转发至该版本,不足容灾机制。还有一种业务场景,如果咱们心愿对处于肯定 UID 范畴的用户流量转发指定灰度环境,是无奈通过 Istio 现有的流量治理规定实现的。此时,您能够抉择阿里云服务网格产品 ASM,是一个对立治理微服务利用流量、兼容 Istio 的托管式平台。ASM 针对上述两个场景都有应答计划,轻松解决您在多语言场景下的全链路灰度诉求。
三种形式比照
下表是三种形式比照,从多个方面进行了比照。
- 如果您偏向于应用无侵入式的 Java Agent 的形式,但又放心自建带来的稳定性问题,您能够抉择 MSE 微服务治理产品,该产品是阿里巴巴外部多年在微服务治理畛域的积淀的产出,经验了各种大促考验。
- 如果您偏向于应用语言无关、无侵入式的 Service Mesh 的形式,但又放心自建带来的稳定性问题,您能够抉择阿里云 ASM 产品,相比开源 Istio,在功能性、稳定性和安全性都有很大的晋升。
流量入口:网关
在分布式应用中,作为流量入口的网关是不可或缺的。在全链路灰度场景中,就要求微服务网关具备丰盛的流量治理能力,反对服务多版本路由,反对对特定路由规定上的申请进行动静打标。对于入口服务可见性问题,网关须要反对多种服务发现形式。安全性问题上,网关作为集群对外的入口能够对所有申请流量进行认证鉴权,保障业务零碎不被非法流量入侵。
在虚拟化期间的微服务架构下,业务通常采纳流量网关 + 微服务网关的两层架构,流量网关负责南北向流量调度和平安防护,微服务网关负责东西向流量调度和服务治理。在容器和 K8s 主导的云原生时代,Ingress 成为 K8s 生态的网关规范,赋予了网关新的使命,使得流量网关 + 微服务网关合二为一成为可能。阿里云 MSE 公布的云原生网关在能力不打折的状况下,将两层网关变为一层,不仅能够节俭 50% 的资源老本,还能够升高运维及应用老本。最重要的是,云原生网关反对与后端微服务治理联动实现端到端的全链路灰度。
从 0 到 1 实际全链路灰度
看到这里,置信大多数读者对全链路灰度有了大略的意识,也理解了几种解决方案以及实现细节。接下来,咱们会基于文中提到的 MSE 云原生网关和 MSE 服务治理产品,从 0 到 1 对全链路灰度进行实际,一方面加深对全链路灰度的意识,另一方面能够理解下阿里云是如何将阿里巴巴外部的最佳实际输入到云产品中。
咱们假如利用的架构由 MSE 云原生网关以及后端的微服务架构(Spring Cloud)来组成,后端调用链路有 3 跳,购物车(a),交易中心(b),库存核心(c),通过客户端或者是 H5 页面来拜访后端服务,它们通过 Nacos 注册核心做服务发现。当初心愿应用全链路灰度能力构建一个灰度环境,不便对服务 A 和服务 C 同时进行灰度验证。
前提条件
必备的资源列表
- 已领有一个 MSE 云原生网关
- 已领有一个 MSE Nacos 注册核心
- 已领有一个 ACK 运维集群
- 已开明 MSE 微服务治理专业版
部署 Demo 应用程序
将上面的文件保留到 ingress-gray.yaml 中,并执行 kubectl apply -f ingress-gray.yaml
以部署利用,这里咱们将要部署 A,B,C 三个利用,A 和 C 利用别离部署一个基线版本和一个灰度版本,B 利用部署一个基线版本。
有以下留神点:
- 全链路灰度能力是与注册核心无关的,本文用例暂以 MSE Nacos 作为注册核心,所以须要将 spring.cloud.nacos.discovery.server-addr 换成业务本人的 Nacos 注册核心地址
- 接入云原生网关的服务,如果须要应用灰度公布,须要在公布服务时在元数据信息减少版本标。在咱们的例子,服务 A 是须要裸露给网关,所以公布时为基线版本增加 spring.cloud.nacos.discovery.metadata.version=base,为灰度版本增加 spring.cloud.nacos.discovery.metadata.version=gray。
# A 利用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-a
name: spring-cloud-a
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-a
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-a
labels:
app: spring-cloud-a
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
- name: spring.cloud.nacos.discovery.server-addr
value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848
- name: spring.cloud.nacos.discovery.metadata.version
value: base
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-a
ports:
- containerPort: 20001
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
# A 利用 gray 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-a-new
name: spring-cloud-a-new
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-a-new
strategy:
template:
metadata:
annotations:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-a
labels:
app: spring-cloud-a-new
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
- name: profiler.micro.service.tag.trace.enable
value: "true"
- name: spring.cloud.nacos.discovery.server-addr
value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848
- name: spring.cloud.nacos.discovery.metadata.version
value: gray
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-a-new
ports:
- containerPort: 20001
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
# B 利用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-b
name: spring-cloud-b
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-b
strategy:
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-b
labels:
app: spring-cloud-b
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
- name: spring.cloud.nacos.discovery.server-addr
value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.2-demo-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-b
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
# C 利用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-c
name: spring-cloud-c
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-c
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-c
labels:
app: spring-cloud-c
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
- name: spring.cloud.nacos.discovery.server-addr
value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.2-demo-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-c
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
# C 利用 gray 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-c-new
name: spring-cloud-c-new
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-c-new
template:
metadata:
annotations:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-c
labels:
app: spring-cloud-c-new
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
- name: spring.cloud.nacos.discovery.server-addr
value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.2-demo-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-c-new
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
实现云原生网关初步配置
第一步,为云原生网关增加 Nacos 服务起源,服务治理,起源治理,点击创立起源,
抉择 MSE Nacos 服务起源,抉择须要关联的 Nacos 注册核心,点击确定。
第二步,导入要通过云原生网关裸露给内部的服务。抉择服务治理,服务列表,点击创立服务。
抉择服务起源为 MSE Nacos,抉择服务 sc-A。
点击服务 A 的策略配置,为入口服务 A 创立多版本,版本划分根据服务注册时所带的元数据信息 version(留神,这里能够是任意能够辨别服务版本的标签值,取决于用户注册服务时所采纳的元数据信息),创立以下两个版本 base 和 gray。
路由配置
创立基线环境的路由匹配规定,关联域名 base.example.com,路由到服务 sc-A 的 base 版本中。
创立灰度环境的路由匹配规定,关联的域名与基线环境保持一致,留神此处减少了申请头相干的配置,并且路由的指标服务为服务 sc-A 的 gray 版本。
这时,咱们有了如下两条路由规定,
此时,拜访 base.example.com
路由到基线环境
curl -H "Host: base.example.com" http://118.31.118.69/a
A[172.21.240.105] -> B[172.21.240.106] -> C[172.21.240.46]
如何拜访灰度环境呢?只须要在申请中减少一个 header x-mse-tag: gray
即可。
curl -H "Host: base.example.com" -H "x-mse-tag: gray" http://118.31.118.69/a
Agray[172.21.240.44] -> B[172.21.240.146] -> Cgray[172.21.240.147]
能够看到 云原生网关 将灰度流量路由到了 A 和 C 的灰度版本,因为 B 没有指定的灰度版本,所以流量主动回退到基线版本。
剖析
从下面能够看出,咱们只须要开明 MSE 微服务治理专业版,在云原生网关配置入口服务的路由规定,并且对入口流量进行灰度染色,即可满足咱们对 A 和 C 全链路灰度的要求。另外还有一个很重要的点是,业务须要自行对节点打标并对入口服务开启链路传递。为 Pod 模板的 Annotations 增加 alicloud.service.tag 键值对实现节点打标,Java Agent 会在业务向注册核心时注销节点时主动为其增加这个元数据信息,同时须要为入口服务的业务容器增加环境变量 profiler.micro.service.tag.trace.enable=true
开启链路传递灰度标识。MSE 服务治理组件默认应用 x-mse-tag 来标识流量,并在整个调用链路中传递。
另外,您能够设置其余自定义或业务已有的字段来标识流量,更多详情操作、场景展现参考文档:https://help.aliyun.com/document_detail/359851.html
总结
本文从单体架构向微服务架构演进过程中带来的挑战开展,着重对其子畛域服务公布在单体架构和微服务架构体系下的状态进行剖析,引出了分布式应用场景中特有的全链路灰度问题。针对业务对全链路能力的要求,介绍了基于物理环境隔离和基于逻辑环境隔离两种计划,其中对基于逻辑环境隔离计划进行详细分析,对波及到的各个技术点也进行了很好的解释,接着提出了三种基于逻辑环境隔离的落地计划,并进行了简略的比照剖析,最初引出了阿里云 MSE 云原生、MSE 服务治理和服务网格 ASM 是如何提供不限于全链路灰度的流量治理能力。
最初,对网关、微服务治理畛域感兴趣的同学,能够 钉钉搜寻群号 34754806 或扫描下方二维码退出用户群交换、答疑。
点击此处,查看微服务治理之全链路灰度直播回放!