作者:
十眠|微服务引擎 MSE 研发工程师
扬少|微服务引擎 MSE 研发工程师
本文摘选自《微服务治理技术白皮书》,该白皮书历经半年多筹备,长达 379 页。心愿通过本书,能对高效解决云原生架构下的微服务治理难题,起到一点点作用,电子版收费下载地址:
https://developer.aliyun.com/…
长按二维码中转下载地址
单体架构下的服务公布
⾸先,咱们先看⼀下在单体架构中,如何对应⽤中某个服务模块进⾏新版本公布。如下图,应⽤中的 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 地址只属于以后的⽹络环境。
这个⽅案⼀般⽤于企业的测试、预发开发环境的搭建,对于线上灰度公布引流的场景来说其灵活性不够。况且,微服务多版本的存在在微服务架构中是粗茶淡饭,须要为这些业务场景采⽤堆机器的⽅式来 保护多套灰度环境。如果您的应⽤数⽬过多的状况下,会造成运维、机器老本过⼤,老本和代价远超收益;如果应⽤数⽬很⼩,就两三个应⽤,这个⽅式还是很⽅便的,能够承受的。
逻辑环境隔离
另⼀种⽅案是构建逻辑上的环境隔离,咱们只需部署服务的灰度版本,流量在调⽤链路上流转时,由流经的⽹关、各个中间件以及各个微服务来辨认灰度流量,并动静转发⾄对应服务的灰度版本。如下图:
上图能够很好展现这种计划的成果,咱们用不同的色彩来示意不同版本的灰度流量,能够看出无论是微服务网关还是微服务自身都须要辨认流量,依据治理规定做出动静决策。当服务版本发生变化时,这个调用链路的转发也会实时扭转。相比于利用机器搭建的灰度环境,这种计划不仅能够节俭大量的机器老本和运维人力,而且能够帮忙开发者实时疾速的对线上流量进行精细化的全链路管制。
那么全链路灰度具体是如何实现呢?通过上⾯的探讨,咱们须要解决以下问题:
1. 链路上各个组件和服务可能依据申请流量特色进⾏动静路由。
2. 须要对服务下的所有节点进⾏分组,可能辨别版本。
3. 须要对流量进⾏灰度标识、版本标识。
4. 须要辨认出不同版本的灰度流量。
接下来,会介绍解决上述问题须要⽤到的技术。
标签路由
标签路由通过对服务下所有节点依照标签名和标签值不同进⾏分组,使得订阅该服务节点信息的服务生产端能够按需拜访该服务的某个分组,即所有节点的⼀个⼦集。服务生产端能够使⽤服务提供者节点上的任何标签信息,依据所选标签的理论含意,生产端能够将标签路由应⽤到更多的业务场景中。
节点打标
那么如何给服务节点增加不同的标签呢?在现在⽕热的云原⽣技术推动下,⼤少数业务都在踊跃进⾏容器化革新之旅。这⾥,我就以容器化的应⽤为例,介绍在使⽤ 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 是须要整个链路传递的。
借助于分布式链路追踪思维,咱们也能够传递⼀些⾃定义信息,⽐如灰度标识。业界常⻅的分布式链路追踪产品都⽀持链路传递⽤户⾃定义的数据,其数据处理流程如下图所示:
逻辑环境隔离
⾸先,须要⽀持动静路由性能,对于 Spring Cloud、Dubbo 开发框架,能够对出⼝流量实现⾃定义 Filter,在该 Filter 中实现流量辨认以及标签路由。同时须要借助分布式链路追踪技术实现流量标识链路传递以及流量⾃动染⾊。此外,须要引⼊⼀个中⼼化的流量治理平台,⽅便各个业务线的开发者定义⾃⼰的全链路灰度规定。如下图所示:
总体上看,实现全链路灰度的能⼒,⽆论是老本还是技术复杂度都是⽐较⾼的,以及前期的保护、扩大都是⾮常⼤的老本,但的确更精细化的进步了公布过程中的利用稳定性。
点击 此处,返回微服务引擎 MSE 官网查看更多详情!