关于微服务:如何解决-Spring-Cloud-下测试环境路由问题

5次阅读

共计 7717 个字符,预计需要花费 20 分钟才能阅读完成。

作者

张乐

开源社区 Spring Cloud Tencent PMC,开源社区 Apollo PMC,腾讯云技术专家、
专一于微服务中间件研发包含:注册核心、配置核心、服务治理核心等。

张皓天

开源社区 Spring Cloud Tencent PMC,腾讯云高级研发工程师,专一于微服务架构畛域,深耕服务治理能力与其余相干中间件研发。

前言

Spring Cloud Tencent 微服务开发框架自六月底正式对外宣发后,受到了许多开发者十分炽热的关注。不到一个月工夫,Github Star 数就已冲破 2000,超过 1000 名开发者退出咱们的社群,并有 20 多个开发者参加奉献我的项目代码,我的项目的热门水平极大地超出咱们的预期,同时也验证了咱们在最后宣发文章里的观点:Spring Boot + Spring Cloud 仍是以后应用相当宽泛开发框架

在这一个月工夫里,Spring Cloud Tencent 的关注者们最关怀的问题就是,Spring Cloud Tencent 后续布局是什么?

在过来的一段时间,咱们的次要精力聚焦在微服务畛域最根本的服务治理原子能力,例如服务发现、动静配置、限流熔断、路由等。Spring Cloud 其它套件基本上也局限于这些根底能力。然而企业真正在实际 Spring Cloud 过程中,发现针对本身具体的业务场景,这些原子能力并不能间接提供解决方案,往往须要做二次开发、定制等。例如定制 Spring Cloud Gateway 的 Filter、加强 Feign、反对各种简单的服务路由场景等。因而,开箱即用的业务通用解决方案对企业来说更具备价值。

综上所述,Spring Cloud Tencent 后续重要的布局之一就是 在一直夯实服务治理原子能力的根底上,提供开箱即用的业务通用解决方案,从工具到计划的降级。

为此 Spring Cloud Tencent 新增了 spring-cloud-tencent-plugin-starts 模块,在此模块下实现不同业务场景的解决方案。现阶段咱们次要聚焦在精细化流量治理能力场景化计划上,并依照开发流程拆分为三个阶段:

  1. 开发测试阶段的多测试环境场景;
  2. 公布阶段的金丝雀公布、蓝绿公布、全链路灰度等;
  3. 生产运行阶段的单元化、AB 测试等。

本期咱们次要聊聊开发测试阶段的多测试环境场景实战,具体介绍 Spring Cloud Tencent 实现多测试环境场景的计划。

一、基础知识

1.1 什么是测试环境路由

在理论的开发过程中,一个微服务架构零碎下的不同微服务可能是由多个团队进行开发与保护的,每个团队只需关注所属的一个或多个微服务,而各个团队保护的微服务之间可能存在互相调用关系。如果一个团队在开发其所属的微服务,调试的时候须要验证残缺的微服务调用链路。此时须要依赖其余团队的微服务,如何部署开发联调环境就会遇到以下问题:

  1. 如果所有团队都应用同一套开发联调环境,那么一个团队的测试微服务实例无奈失常运行时,会影响其余依赖该微服务的利用也无奈失常运行。
  2. 如果每个团队有独自的一套开发联调环境,那么每个团队不仅须要保护本人环境的微服务利用,还须要保护其余团队环境的本身所属微服务利用,效率大大降低。同时,每个团队都须要部署残缺的一套微服务架构利用,老本也随着团队数的减少而大大回升。

此时能够应用测试环境路由的架构来帮忙部署一套运维简略且老本较低开发联调环境。测试环境路由是一种基于服务路由的环境治理策略,外围是保护一个稳固的基线环境作为根底环境,测试环境仅须要部署须要变更的微服务。多测试环境有两个根底概念,如下所示:

  1. 基线环境(Baseline Environment): 残缺稳固的根底环境,是作为同类型下其余环境流量通路的一个兜底可用环境,用户应该尽量保障基线环境的完整性、稳定性。
  2. 测试环境(Feature Environment): 一种长期环境,仅可能为开发 / 测试环境类型,测试环境不须要部署全链路残缺的服务,而是仅部署本次有变更的服务,其余服务通过服务路由的形式复用基线环境服务资源。

部署实现多测试环境后,开发者能够通过肯定的路由规定形式,将测试申请打到不同的测试环境,如果测试环境没有相应的微服务解决链路上的申请,那么会降级到基线环境解决。因而,开发者须要将开发新测试的微服务部署到对应的测试环境,而不须要更新或不属于开发者治理的微服务则复用基线环境的服务,实现对应测试环境的测试。

尽管测试环境路由是一个绝对成熟的开发测试环境解决方案,然而可能开箱即用的生产开发框架却不多,往往须要开发者二次开发相应的性能。因而须要一个绝对欠缺的解决方案来帮忙实现测试环境路由,简化开发难度并晋升开发效率。

1.2 服务路由

服务路由模型

服务路由形象出最简化的模型如下图所示,解决的是 “哪些申请转发到哪些实例” 的问题。细化来看,蕴含三个问题:

  1. 如何准确标识申请?
  2. 如何准确标识实例?
  3. 如何转发?

(图:服务路由模型示意图)

在流量的微观世界里,对立通过标签(属性)来标识一个实体,例如申请有起源调用服务、指标环境标签等,服务实例则有版本号、实例分组、环境分组等标签。服务路由则是将满足标签匹配条件的申请转发到满足匹配条件的服务实例。所以服务路由的模型可拆解出如下的的专业术语:

  • 服务实例染色(为服务实例设置标签信息)
  • 量染色(为申请设置标签信息)
  • 服务路由(依据路由策略,把申请转发到指标实例)

服务实例标签如何传递到调用方

服务实例注册到注册核心时,会带上标签信息。服务调用方从注册核心获取到服务实例信息就蕴含了实例的标签信息。

标签全链路透传

有一类申请标签数据须要在业务响应链路上始终传递,例如全链路追踪里的 TraceId、测试环境路由的 FeatureEnv 标签等。

服务路由和负载平衡的区别

服务路由和负载平衡都是解决抉择服务实例的问题。区别在于服务路由是从全量的服务实例中挑选出一批满足路由规定的服务实例,而负载平衡则是从路由匹配之后的服务实例列表中挑选出一个适宜解决申请的实例。

二、测试环境路由实现原理

2.1 计划总览

测试环境路由的样例实现以下图为例,一共有两个测试环境以及一个基线环境。流量从端到端会顺次通过以下组件:App -> 网关 -> 用户核心 -> 积分核心 -> 活动中心。

(图:测试环境路由示意图)

依据上一节服务路由章节所述,为了达到测试环境路由的能力,开发工作须要做三件事件:

  1. 服务实例染色(标识实例属于哪个测试环境)
  2. 流量染色(标识申请应该被转发到哪个测试环境)
  3. 服务路由

    a 网关依据申请的指标测试环境标签转发到对应的指标测试环境的用户核心。

    b 服务调用时,优先转发到同测试环境下的指标服务实例,如果同测试环境下没有服务实例则转发到基线环境。

以下三大节,将会具体介绍这三局部的原理。

2.2 服务实例染色

在多测试环境的场景中,须要对每个测试环境部署的实例进行辨别,因而须要在实例上打 <featureenv= 测试环境名 > 的标签。Spring Cloud Tencent 一共反对三种服务实例染色形式。

形式一:配置文件

在 Spring Boot 的 application.yml 配置文件里配置以下内容即可实现染色:

spring:
  cloud:
    tencent:
      metadata:
        content:
          idc: shanghai
          env: f1

Spring Cloud Tencent 利用在启动时,读取配置文件并解析出 idc=shanghai 和 env=f1 标签信息。

如果以上配置文件放在我的项目源码里,要实现不同的实例具备不同的标签值则须要打不同包。能够通过以下两种形式实现同一个运行包设置不同的标签值:

  1. 通过 -D 启动参数笼罩,例如 -Dspring.cloud.tencent.metadata.content.idc=guangzhou
  2. 通过 Spring Boot 规范形式,把 application.yml 外挂本地磁盘上

形式二:环境变量

环境变量在容器场景下十分不便,Spring Cloud Tencent 约定了前缀为 SCT_METADATA_CONTENT_ 的环境变量为实例的标签信息,例如:

  • SCT_METADATA_CONTENT_IDC=shanghai
  • SCT_METADATA_CONTENT_ENV=f1

Spring Cloud Tencent 利用在启动时,主动会读取环境变量并解析出 IDC=shanghai 和 ENV=f1 标签信息。

形式三:自定义实现 SPI

后面两种形式为 Spring Cloud Tencent 内置的形式,然而不肯定合乎每个生产我的项目的标准,因而 Spring Cloud Tencent 还提供了一种容许开发者自定义标签 Provider 的形式。例如以下两种实际场景:

  1. 把实例标签放到机器上的某一个配置文件里,例如 /etc/metadata。
  2. 利用启动时,调用公司的 CMDB 接口获取元信息。

这种场景下,只有实现 InstanceMetadataProvider SPI 扩大即可。

2.3 流量染色

流量染色即为每个申请打上指标测试环境标签,路由转发时依据申请标签匹配指标服务实例。而流量染色能够分为以下几种形式:

形式一:动态染色

2.2 大节介绍了能够为服务实例设置一系列的标签信息,例如 idc=shanghai、env=f1 等。在有些场景下,冀望所有通过以后实例的申请都带上以后实例的标签信息。例如通过 env=f1 的实例的申请都携带 env=f1 的标签信息。

服务实例染色有三种形式,对应的定义哪些标签须要作为申请标签透传到链路上也有三种形式,核心思想就是定义须要全链路传递的标签键值对的键列表。

  1. 通过配置文件的 spring.cloud.tencent.metadata.content.transitive=[“idc”, “env”] 配置项指定
  2. 通过 SCT_METADATA_CONTENT_TRANSITIVE=IDC,ENV 环境变量指定
  3. 通过实现 InstanceMetadataProvider#getTransitiveMetadataKeys() 办法指定

形式二:动静染色

动态染色是把服务实例的某些标签作为申请标签,服务实例标签绝对动态,利用启动后初始化一次之后就不再变更。然而在理论的利用场景下,不同的申请往往须要设置不同的标签信息。此时则须要通过动静染色的能力。

为申请动静染色也非常简单,只需减少以 X-Polaris-Metadata-Transitive- 为前缀的 HTTP 申请头即可,例如:X-Polaris-Metadata-Transitive-featureenv=f1。这样 featureenv=f1 就可能作为申请标签在链路上透传。

形式三:网关流量染色

网关经常作为流量的入口或者中转站。通过网关的申请,能够依据某些染色规定为申请减少标签信息。例如满足申请参数 uid=1000 申请打上 featureenv=f1 标签。

网关流量染色是十分实用的能力,在 Spring Cloud Tencent 里实现了非常灵活基于染色规定的 Spring Cloud Gateway 染色插件。例如以下染色规定能够实现为 uid=1000 的申请打上 featureenv=f1 标签、uid=1001 的申请打上 featureenv=f2 标签。更具体的染色规定,能够参考文档。

{
    "rules":[
        {
            "conditions":[
                {"key":"${http.query.uid}",
                    "values":["1000"],
                    "operation":"EQUALS"
                }
            ],
            "labels":[
                {
                    "key":"featureenv",
                    "value":"f1"
                }
            ]
        },
        {
            "conditions":[
                {"key":"${http.query.uid}",
                    "values":["1001"],
                    "operation":"EQUALS"
                }
            ],
            "labels":[
                {
                    "key":"featureenv",
                    "value":"f2"
                }
            ]
        }
    ]
}

同时 Spring Cloud Tencent 也预留了 TrafficStainer SPI,用户能够实现自定义流量染色插件。

2.4 Spring Cloud Tencent 路由性能原理

北极星提供了十分欠缺的服务治理能力,下层的服务框架基于北极星原生 SDK 就能疾速实现弱小的服务治理能力。Spring Cloud Tencent 就是在北极星的根底上实现了服务路由能力。

北极星服务路由原理

北极星服务路由实现原理并不简单,如下图所示,从注册核心获取到所有实例信息,再通过一系列的 RouterFilter 插件过滤出满足条件的实例汇合。

(图:北极星服务路由执行链)

在多测试环境场景下次要用到了 MetadataRouter(元数据路由)插件,此插件外围能力是 依据申请的标签齐全匹配服务实例的标签。

例如申请有两个标签 key1=value1 和 key2=value2,MetadataRouter 则会筛选出所有实例中蕴含同时满足 key1=value1 和 key2=value2 的服务实例。在多测试环境场景下,Spring Cloud Tencent 缺省应用 featureenv 标签,通过 featureenv 标签筛选出属于同一个测试环境的服务实例。

Spring Cloud Tencent 服务路由原理

Spring Cloud Tencent 实现路由外围分成两个局部:

  1. 扩大 RestTemplate、Feign、SCG 获取申请的标签信息并塞到 RouterContext(路由信息上下文)里。
  2. 扩大 Spring Cloud 负载平衡组件(Hoxton 版本之前为 Ribbon,2020 版本之后为 Spring Cloud LoadBalancer),在扩大的实现里调用北极星的服务路由 API 实现服务实例过滤。

扩大局部逻辑较为简单,感兴趣的读者能够参考 spring-cloud-starter-tencent-polaris-router 模块源码。

三、测试环境路由用户操作指引

在上一节中具体介绍了测试环境路由的实现原理,这一节则具体介绍站在用户的视角须要操作的内容。

通过 Spring Cloud Tencent 实现流量的测试环境路由非常简单,外围蕴含三步:

  1. 服务减少测试环境路由插件依赖
  2. 部署的实例打上环境标签
  3. 为申请流量打上环境标签

实现以上三个步骤即可。

3.1 增加测试环境路由插件依赖

Spring Cloud Tencent 中的 spring-cloud-tencent-featureenv-plugin 模块闭环了测试环境路由全副能力,所有服务只须要增加该依赖即可引入测试环境路由能力。

3.2 服务实例打上环境标签

spring-cloud-tencent-featureenv-plugin 默认以 featureenv 标签作为匹配标签,用户也能够通过零碎内置的 system-feature-env-router-label=custom_feature_env_key 标签来指定测试环境路由应用的标签键。以下三种形式以默认的 featureenv 作为示例。

形式一:配置文件

在服务实例的配置文件中增加配置,如在 bootstrap.yml 增加如下所示即可:

spring:
  cloud:
    tencent:
      metadata:
        content:
          featureenv: f1  # f1 替换为测试环境名称

形式二:环境变量

在服务实例所在的操作系统中增加环境变量也可进行打标,例如:SCT_METADATA_CONTENT_featureenv=f1

形式三:SPI 形式

自定义实现 InstanceMetadataProvider#getMetadata() 办法的返回值里里蕴含 featureenv 即可。

基线环境标签值

留神,基线环境部署的服务实例不须要设置 featureenv 标签,表明其不属于任何测试环境,才可在申请没有匹配到对应测试环境的时候,匹配到基线环境。

3.3 流量染色

形式一:客户端染色(举荐)

如下图所示,在客户端收回的 HTTP 申请里,新增 X-Polaris-Metadata-Transitive-featureenv=f1 申请头即可实现染色。该形式是让开发者在申请创立的时候依据业务逻辑进行流量染色。

(图:客户端染色示意图)

形式二:网关动静染色(举荐)

动静染色是开发者配置肯定的染色规定,让流量通过网关时主动染色,应用起来相当不便。例如把 uid=1 用户的申请都转发到 f1 环境,把 uid=0 用户的申请都转发到 f2 环境。只须要配置一条染色规定即可实现。

(图:网关动静染色示意图)

Spring Cloud Tencent 通过实现 Spring Cloud Gateway 的 GlobalFilter 来实现流量染色插件,开发者只须要增加 spring-cloud-tencent-gateway-plugin 依赖,并在配置文件中关上染色插件开关(spring.cloud.tencent.plugin.scg.staining.enabled=true)即可引入流量染色能力。

形式三:网关动态染色

往申请中退出固定的 Header 是网关最常见的插件,如下图所示。能够在每个环境部署一个网关,所有通过网关的申请都减少 X-Polaris-Metadata-Transitive-featureenv=f1 申请头即可。此种形式须要每个环境部署网关,老本高,所以应用频率绝对较低。

(图:网关动态染色示意图)

实现以上操作步骤即可实现测试环境路由,读者可运行 Spring Cloud Tencent 下 polaris-router-featureenv-example 残缺体验。

四、总结

测试环境路由在微服务架构零碎的开发阶段是十分实用的性能,可能大大降低测试环境的保护老本、资源老本,同时可能极大的进步研发效率。通过操作指引的章节能够看出通过 Spring Cloud Tencent 实现测试环境路由非常简单的,只须要部署的服务实例减少相应的环境标签以及在申请头中减少一个标签即可。

业界常见的测试环境路由实现计划往往须要下发路由规定给链路上的服务,从而实现路由能力。然而通过北极星的元数据路由能力,整个计划里无需下发任何路由规定,只须要在实例设置相应的标签信息即可,操作老本非常低。

如果我的项目刚好应用 Spring Cloud Gateway 作为网关,那么集成 Spring Cloud Tencent 里的网关染色插件可能进一步升高流量染色老本,客户端无需做任何事件,只须要配置网关染色规定即可实现流量染色。

目前 Spring Cloud Tencent 次要实现了微服务之间调用流量的测试环境路由能力,不波及音讯队列、任务调度的测试环境路由能力。

\

五、欢送共建

如果您所在我的项目正在应用 Spring Cloud 框架,并且

  • 积淀出了十分实用的通用插件能力和场景化解决方案
  • 目前正遇到一些落地难题
  • 对 Spring Cloud Tencent 我的项目感兴趣

十分欢迎您跟咱们一起打磨更多实用且通用的能力,共建满足各类理论生产场景应用的微服务开发框架。您的一个倡议、Issue、Pull Request 甚至只是一个小小的 Star 都是对 Spring Cloud Tencent 社区极大的反对。

\

Github 地址:https://github.com/Tencent/sp…

正文完
 0