如何解决 Spring Cloud 下测试环境路由问题

前言

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. 怎么转发?

如何解决 Spring Cloud 下测试环境路由问题

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

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

  • 服务实例染色 (为服务实例设置标签信息)
  • 流量染色(为恳求设置标签信息)
  • 服务路由(依据路由策略,把恳求转发到方针实例)

服务实例标签怎么传递到调用方

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

标签全链路透传

有一类恳求标签数据需求在事务响应链路上一向传递,例如全链路追踪里的 TraceId 、测验环境路由的 FeatureEnv 标签等。

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

服务路由和负载均衡都是处理选择服务实例的问题。区别在于服务路由是从全量的服务实例中挑选出一批满意路由规矩的服务实例,而负载均衡则是从路由匹配之后的服务实例列表中挑选出一个适合处理恳求的实例。

二、测验环境路由完成原理

2.1 计划总览

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

如何解决 Spring Cloud 下测试环境路由问题

图:测验环境路由示意图

依据上一节服务路由章节所述,为了到达测验环境路由的才能,开发工作需求做三件工作:

  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 插件过滤出满意条件的实例调集。

如何解决 Spring Cloud 下测试环境路由问题

图:北极星服务路由履行链

在多测验环境场景下首要用到了 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 恳求头即可完成染色。该方法是让开发者在恳求创建的时候依据事务逻辑进行流量染色。

如何解决 Spring Cloud 下测试环境路由问题

图:客户端染色示意图

方法二:网关动态染色(推荐)

动态染色是开发者装备必定的染色规矩,让流量通过网关时主动染色,运用起来适当便利。例如把 uid=1 用户的恳求都转发到 f1 环境,把 uid=0 用户的恳求都转发到 f2 环境。只需求装备一条染色规矩即可完成。

如何解决 Spring Cloud 下测试环境路由问题

图:网关动态染色示意图

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 下测试环境路由问题

图:网关静态染色示意图

完结以上操作过程即可完成测验环境路由,读者可运转 Spring Cloud Tencent 下 polaris-router-featureenv-example 完好体验。

四、总结

测验环境路由在微服务架构体系的开发阶段是十分有用的功用,可以大大下降测验环境的保护本钱、资源本钱,一起可以极大的提高研制功率。通过操作指引的章节可以看出通过 Spring Cloud Tencent 完成测验环境路由十分简略的,只需求布置的服务实例添加相应的环境标签以及在恳求头中添加一个标签即可。

业界常见的测验环境路由完成计划往往需求下发路由规矩给链路上的服务,然后完成路由才能。可是通过北极星的元数据路由才能,整个计划里无需下发任何路由规矩,只需求在实例设置相应的标签信息即可,操作本钱十分低。

假如项目刚好运用 Spring Cloud Gateway 作为网关,那么集成 Spring Cloud Tencent 里的网关染色插件可以进一步下降流量染色本钱,客户端无需做任何工作,只需求装备网关染色规矩即可完成流量染色。

现在 Spring Cloud Tencent 首要完成了微服务之间调用流量的测验环境路由才能,不涉及消息队列、使命调度的测验环境路由才能。