就近路由
功能描述
北极星提供基于 地域(region) - 城市(zone) - 园区(campus) 这3元组组成的地域信息进行就近路由的能力,能够根据主调的地域信息,结合被调实例的地域信息,进行匹配。实例本身的地域信息来源于有以下几个途径
服务端的 CMDB 插件
- 参考 cmdb 插件开发
客户端的 Location 插件
- 提供 Location 插件,用户可以根据 polaris客户端 中对于 Location 插件的定义,根据客户端所在环境的特性来实现不同的本地地址位置信息获取插件
- env: 将地理位置信息注入至客户端所在机器的环境中,客户端就可以基于系统环境变量自动获取地理位置信息
配置设计
polaris-go 客户端使用
SDK配置属于客户端全局配置,基于该SDK实例所发起的服务发现,都遵循该就近路由策略。 由于就近路由能力通过SDK服务路由模块的插件进行提供,因此就近路由相关配置,也作为插件的特有配置来进行提供。
global:
# 地址提供插件,用于获取当前SDK所在的地域信息
location:
providers:
- type: local
region: ${REGION} # 从环境变量 REGION 中读取
zone: ${ZONE} # 从环境变量 ZONE 中读取
campus: ${CAMPUS} # 从环境变量 CAMPUS 中读取
consumer:
serviceRouter:
# 服务路由链
chain:
- nearbyBasedRouter
# 插件特定配置
plugin:
nearbyBasedRouter:
# 默认就近区域:默认城市
matchLevel: zone
# 最大就近区域,默认为空(全匹配)
maxMatchLevel: zone
polaris-java 客户端使用
SDK配置属于客户端全局配置,基于该SDK实例所发起的服务发现,都遵循该就近路由策略。 由于就近路由能力通过SDK服务路由模块的插件进行提供,因此就近路由相关配置,也作为插件的特有配置来进行提供。
global:
location:
providers:
- type: local
options:
region: ${REGION:} # 从环境变量 REGION 中读取
zone: ${ZONE:} # 从环境变量 ZONE 中读取
campus: ${CAMPUS:} # 从环境变量 CAMPUS 中读取
serviceRouter:
chain:
# 就近路由
- nearbyBasedRouter
plugin:
nearbyBasedRouter:
#描述: 就近路由的最小匹配级别。region(大区)、zone(区域)、campus(园区)
matchLevel: zone
#描述: 最大匹配级别
maxMatchLevel: all
服务配置
就近流程
初始化
- 用户调用NewConsumerAPI或者NewProviderAPI后
- SDK 会使用客户端节点的 IP,往 Polaris 服务端查询该 IP 对应的 CMDB 信息,查询后的结果后返回给客户端
- 如果查询的结果中,没有携带地址信息,则客户端会走自己本地的 CMDB 插件查询客户端的地理位置信息
地域匹配
服务调用过程中,使用拉取的客户端地域信息,进行全词匹配。匹配规则如下:
- 优先按照 matchLevel 进行匹配,匹配不成功(实例不存在或者可用实例比例少于阈值),则进行降级
- 就近降级按照 degrade 所配置的策略进行降级,会进行逐级的降级匹配,直到 lowestMatchLevel
降级策略
降级策略:服务实例不可用 | 降级策略:服务实例不存在 | |
---|---|---|
matchLevel区域不存在实例 | 逐级降级直到maxMatchLevel。若实例全部不存在,返回LocationMismatch错误 | 逐级降级直到maxMatchLevel,若都不存在,返回LocationMismatch错误 |
matchLevel区域存在实例,区域中不可用实例百分比大于等于降级比例 | 返回matchLevel区域实例 | 逐级降级直到maxMatchLevel,若都不满足健康实例返回条件,返回实例数大于0的最小区域实例 |
被调信息异常策略
maxMatchLevel != “” | maxMatchLevel == “” | |
---|---|---|
被调实例对应的CMDB字段缺失 | 忽略该实例 | 当降级到最高匹配级别(全匹配)时,会返回这部分服务实例 |
跨机房容灾场景
背景
服务端有广州云、深圳、南京云设备。客户端在深圳。 那么深圳客户端访问这个服务端时,返回实例列表由深圳、广州、南京实例组成,同时设置优先级,让深圳客户端优先访问深圳;然后是广州(同可用区);最后是南京
解决方案
假设存在服务A,服务A下面节点存在分别属于深圳、广州、南京的实例,CMDB信息如下:
- 华南/ap-guangzho/ap-guangzhou-3
- 华南/ap-shenzhen/ap-shenzhen-2
- 华东/ap-nanjing/ap-nanjing-4
客户端配置:
consumer:
serviceRouter:
plugin:
nearbyBasedRouter:
# 默认按zone进行就近
matchLevel: zone
就近逻辑
客户端配置 matchLevel: zone,默认只访问同 zone(深圳) 的实例,当深圳可用区无实例后,降级访问 region(华南) 的 实例(可访问广州的实例),当华南地区实例也达到降级条件后,降级访问全部 region(包含华东-南京) 的实例