-
Notifications
You must be signed in to change notification settings - Fork 495
服务路由之元数据路由
服务实例有元数据信息,例如 idc、version 等。请求流量也有标签信息,例如 sourceService、version 等。通过匹配流量标签和实例标签来实现路由称之为元数据路由。
服务实例染色即服务实例启动的时候,通过某些方式获取到当前实例的元信息,并注册到注册中心时携带元信息请参考 服务注册元数据
流量染色即为每个请求打上标签,路由转发时根据请求标签匹配请求。而流量染色可以分为以下几种方式:
小节介绍了可以为服务实例设置一系列的标签信息,例如 idc=shanghai、env=f1 等。在有些场景下,期望所有经过当前实例的请求都带上当前实例的标签信息。例如经过 env=f1 的实例的请求都携带 env=f1 的标签信息。
服务实例染色有三种方式,对应的定义哪些标签需要作为请求标签透传到链路上也有三种方式,核心思想就是定义需要全链路传递的标签键值对的键列表。
- 通过配置文件的
spring.cloud.tencent.metadata.content.transitive=["idc", "env"]
配置项指定 - 通过
SCT_METADATA_CONTENT_TRANSITIVE=IDC,ENV
环境变量指定 - 通过实现
InstanceMetadataProvider#getTransitiveMetadataKeys()
方法指定
静态染色是把服务实例的某些标签作为请求标签,服务实例标签相对静态,应用启动后初始化一次之后就不再变更。但是在实际的应用场景下,不同的请求往往需要设置不同的标签信息。此时则需要通过动态染色的能力。
为请求动态染色也非常简单,只需增加以 X-Polaris-Metadata-Transitive-
为前缀的 HTTP 请求头即可,例如:X-Polaris-Metadata-Transitive-featureenv=f1
。这样 featureenv=f1
就能够作为请求标签在链路上透传。
前面两小节介绍了服务实例染色以及流量染色,这一小节来介绍一下元数据路由。
既然服务实例都有元数据标签,在某些场景下,服务调用时优先调用到跟主调方具有相同元数据标签的被调方实例。如下图所示:
当 OrderSevice
调用 UserService
时,期望同环境实例优先互相调用。
最典型的实际场景为线下多特性环境:
当 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
。
- 根据服务名(user-service)获取目标服务全量实例地址集合
- 这一步中,SCT 只会返回健康的实例集合。细节可参考源码PolarisLoadBalancer.java
- 根据元数据路由规则从全量实例中挑出部分满足规则的实例子集
- 这一步中,SCT 会执行一次地址 Filter 链,输入是全量地址,输出是经过所有地址 Filter 之后的结果。其中一个 Filter 就是元数据路由 Filter MetadataRouter。执行 Filter 链的调用代码请参考:PolarisLoadBalancerCompositeRule#doRouter
- 根据第二步的实例子集,执行负载均衡策略,选中其中一个实例。并替换请求 Url 例如:
http://192.168.1.1:8080/user/get
- 执行负载均衡调用代码请参考:PolarisLoadBalancerCompositeRule#choose
- 您在使用过程中遇到任何问题,请提 Issue 或者加入我们的开发者群告诉我们,我们会在第一时间反馈
- Spring Cloud Tencent 社区期待您的加入,一个 Star、PR 都是对我们最大的支持
- 项目介绍
- 使用指南
- 最佳实践
- 开发文档
- 学习资料