Skip to content

服务路由之元数据路由

lepdou edited this page Jul 28, 2022 · 10 revisions

元数据路由简介

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

元数据路由核心包含三个部分:

  1. 服务实例染色 (为服务实例设置标签信息)
  2. 流量染色(为请求设置标签信息)
  3. 服务路由(根据路由策略,把请求转发到目标实例)

接下去将会详细介绍三部分内容。

服务实例染色

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

流量染色

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

方式一:静态染色

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

元数据路由

以一个模拟的业务场景为例,期望所有 app 过来的请求都转发到专门为 app 搭建的一套环境,而 web 过来的请求都转发到专门为 web 搭建的一套环境。

image

此时一个请求带有 source=appsystem-metadata-router-keys=source 两个标签。app 组和 web 组部署的两套环境中的实例都带有相应的 source 标签。在网关转发流量时,根据 source 标签匹配流量和服务实例,即可完成需求。

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

需要额外说明 system-metadata-router-keys=source 的作用,因为请求流量可能具有很多标签,但是用于元数据路由匹配的标签是其中的子集。所以通过 system-metadata-router-keys=key1,key2 特定的系统流量标签来指定哪些 key 作为元数据路由匹配的标签。

元数据路由原理篇

元数据路由的原理其实非常简单,以 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