Skip to content

服务路由之元数据路由

lepdou edited this page Jul 25, 2022 · 10 revisions

元数据路由简介

服务实例有元数据信息,例如 idc、version 等。请求流量也有标签信息,例如 sourceService、version 等。通过匹配流量标签和实例标签来实现路由称之为元数据路由。

服务实例染色

服务实例染色即服务实例启动的时候,通过某些方式获取到当前实例的元信息,并注册到注册中心时携带元信息请参考 服务注册元数据

流量染色

流量染色即为每个请求打上标签,路由转发时根据请求标签匹配请求。而流量染色可以分为以下几种方式:

方式一:静态染色

小节介绍了可以为服务实例设置一系列的标签信息,例如 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 就能够作为请求标签在链路上透传。

元数据路由

前面两小节介绍了服务实例染色以及流量染色,这一小节来介绍一下元数据路由。

既然服务实例都有元数据标签,在某些场景下,服务调用时优先调用到跟主调方具有相同元数据标签的被调方实例。如下图所示:

image

OrderSevice 调用 UserService 时,期望同环境实例优先互相调用。

最典型的实际场景为线下多特性环境:

image

当 SvcA 和 SvcD 需要在某一次迭代中进行联调时,无需部署一套包含全链路 SvcA,SvcB,SvcC,SvcD 的环境,一方面成本太高,另一方面 SvcB 和 SvcC 可能属于其它团队,不方便部署。 只需要在 dev1 里部署 SvcA 和 SvcD 打上

  • SCT_METADATA_CONTENT_env=dev1 (指定当前实例所属的环境信息)
  • SCT_METADATA_CONTENT_TRANSITIVE=env (指定 env 作为链路传递的标签)
  • SCT_METADATA_CONTENT_system-metadata-router-keys=env (指定 env 作为元数据匹配的标签)

即可实现如上效果。

在上面的场景下,每一个服务节点在调用下游服务时都要优先调用 env=dev1 的服务,而 env=dev1 这个信息是链路起始节点 SvcA 发出的请求里携带的。所以需要通过一种机制告诉 SCT 哪些元信息需要在链路上传递。

指定元数据路由匹配的标签

请求和实例都有一系列的标签信息,那么哪些标签被用来元数据匹配的标签呢?通过特殊的系统标签 system-metadata-router-keys=key1,key2 来指定 key1 和 key2 作为匹配标签。

元数据路由操作篇

使用元数据路由非常简单,在第一章中其实都已经有介绍到,这一章节再总结一下。

步骤一:基础操作

注意:1.5.0 版本后才支持元数据路由

请参考 服务路由基础操作 文档,引入依赖以及增加配置。

步骤二:元数据打标

方式一

spring:
  cloud:
    tencent:
      metadata:
        content:
          idc: shanghai
          env: dev1
        transitive: # 指定需要传递的元数据 key
          - idc
          - env

方式二

# 定义元数据
SCT_METADATA_CONTENT_${key1}=value1 
SCT_METADATA_CONTENT_${key2}=value2

# 指定需要传递的元数据 key
SCT_METADATA_CONTENT_TRANSITIVE=${key1}

方式三

SPI 的方式,待版本支持后补充。

元数据路由原理篇

元数据路由的原理其实非常简单,以 feign 调用为例,例如调用 http://user-serivce/user/get

  1. 根据服务名(user-service)获取目标服务全量实例地址集合
  1. 根据元数据路由规则从全量实例中挑出部分满足规则的实例子集
  • 这一步中,SCT 会执行一次地址 Filter 链,输入是全量地址,输出是经过所有地址 Filter 之后的结果。其中一个 Filter 就是元数据路由 Filter MetadataRouter。执行 Filter 链的调用代码请参考:PolarisLoadBalancerCompositeRule#doRouter
  1. 根据第二步的实例子集,执行负载均衡策略,选中其中一个实例。并替换请求 Url 例如:http://192.168.1.1:8080/user/get
Clone this wiki locally