-
Notifications
You must be signed in to change notification settings - Fork 886
Description
背景
希望 Kitex 能够原生支持 xDS 协议 ,让 Kitex 服务能够以 Proxyless 的模式被服务网格统一纳管,从而丰富网格数据面部署架构形态,让用户可以在不同场景下有更多更适合特定场景的部署形态选择
目标
- 完成 Kitex 对接 xDS 之后整体架构形态设计
- 完成 Kitex 框架治理能力如何适配 xDS 模型的概要设计
设计介绍
整体架构
整体主要有几个模块组成:
- Control Plane:控制面,负责管理数据面并基于 xDS 协议下发治理规则
- Kitex Application:Kitex 内部整体主要分为两层
- xDS 层:
- xDS Client:封装基于 xDS 协议与控制面交互逻辑
- xDS Resource Manger:管理 xDS 各协议资源的缓存,并对外提供发布订阅能力
- 治理能力层:基于框架提供的治理能力拓展机制,来适配 xDS 模型,实现各种数据面治理能力
- xDS 层:
框架治理能力适配
为了对接治理能力,框架需要做的适配包括以下几部分:
- 添加
RouterMW
,顺序在内置中间件的第一位(动态路由后才能确定之后的配置)。 - 扩展
Resolver
接口实现XdsResolver
,判断服务发现类型,基于 eds 获取实例信息。 - 扩展
LoadBalancer
接口实现XdsLoadbalancer
,根据 cds 动态调整负载均衡策略。
各种治理能力适配思路如下
1. 服务注册
Istio 虽然本身不提供服务注册中心,但是内部维护了统一的服务模型和服务注册表,并且支持集成两种类型的服务注册中心 Provider
- Kubernetes:基于 K8S APIServer List-Watch ,注册并发现 Kubernetes 上的服务
- External:注册并发现外部服务,其中外部服务以 ServiceEntries 的形式定义,可以直接 ServiceEntry CRD 描述,也可以通过 MCP-over-xDS 的方式,以外部数据源的方式注册进来
因此,我们在该方案中无需去设计并实现一套服务注册流程了,只需要直接去对接现有的服务注册中心即可。
2. 动态路由
- 增加一个 xDS Router MW 来负责 Pick Cluster(路由),watch 目标服务的 LDS 及 RDS
- 感知 LDS 变化,并提取目标服务的 LDS 中的 Filter Chain 及其 inline RDS
- 感知 RDS 变化,根据 VirtualHost 和 ServiceName 来匹配(支持前缀、后缀、精确、通配),获取目标服务的路由配置
- 遍历处理匹配到的 RDS 中的路由规则,路由规则主要分为两部分(参考:路由规范定义):
- Match(支持前缀、后缀、精确、通配等),目前版本我们支持以下两种即可:
1. Path(必须项):从 rpcinfo 提取 Method进行匹配
2. HeaderMatcher(可选项):可自定义需要匹配的元数据,比如 metainfo 内的 key-value。 - Route:
1. Cluster:标准 Cluster
2. WeightedClusters(权重路由):MW 内根据权重来选择 cluster
3. 将选择到的 Cluster 写入 EndpointInfo.Tag,用于之后的服务发现。
3. 服务发现
基于 Kitex 的 Resolver 接口,拓展一个 XDSResolver 来进行服务发现。
- 根据 RDS 找到对应的 CDS (Pick Cluster)之后,进入 Resolve 阶段,通过根据 CDS 获取对应的 Cluster 配置,包括负载均衡策略、熔断等。之后拉取 EDS 资源以获取实例信息,并根据对应的 LB 策略,pick 出最终的一个 Endpoint。
服务发现类型包括以下几种:
- Static:直接返回实例的地址
- Static DNS:数据面需要执行 DNS 解析,以获得所有的实例信息。(异步、周期性地解析)
- Logical DNS:执行 DNS 解析,只有当需要建立连接时才使用返回实例信息中的第一个。static DNS 的返回结果是完整的实例信息,当两次的结果不同,则需要清理连接。而 logic DNS 则会维持连接,直至被回收。
- EDS:与控制面交互,发送 eds 请求,以获得实例信息。
4. 负载均衡
Lb policy 包含在 CDS 内,所以 lb 策略的变化是在动态路由选定 cluster 之后获取并应用的。
Kitex 支持自定义 LoadBalancer,实际上就是根据lb策略,从服务发现获得的实例列表内选取一个实例进行调用。
type Loadbalancer interface {
GetPicker(discovery.Result) Picker // 之后添加入参ctx
Name() string // unique key
}
如果希望动态调整 lb 策略,需要扩展一个 XDSLoadBalancer 。
在 GetPicker 的实现内完成 lb 策略的获取 (CDS),及不同策略的实现。
5. 超时控制
根据 RDS 中的 timeout 配置来动态调整 RPC Timeout Middleware 的 RPCInfo 中的超时时间即可,实现方式:
- xdsRouterMW 内获取到 timeout 配置,设置到 rpcinfo 的 config 中,之后会被用于请求的超时时间设置。
6. 熔断器
Istio 支持的熔断配置相较于 Kitex 会更丰富些,除了异常检测之外,还额外支持对连接池的控制,并且每种熔断策略支持的可配置项也非常完备
我们这期先支持基础的异常检测熔断策略,大致流程如下:
- 在 xDS Router MW 中,我们完成 Pick Cluster 的同时,也会拿到相应目标 Cluster 的熔断策略,比如连续请求错误个数(这期我们只考虑异常检测这种熔断策略)
- 启用熔断,并调用 CBSuite 的 UpdateServiceCBConfig 和 UpdateInstanceCBConfig 来动态更新 Key 的阈值
7. 重试
RDS 中会携带 retry policy 规则,Kitex 可以根据这个动态调整其客户端重试策略