大纲,待整理!

适用于小规模项目,节约成本的无感知切换方案。

《Fiegn 参数透传》

《Ribbon Rule》

灰度发布概念
code.zip

一、基于 Ribbon Rule 的灰度发布原理分析

1.1、Ribbon 调用分析

在 Eureka + Ribbon + Feign 为组合的请求处理中,一次请求发起的逻辑流程如下
01.png
如图,

Eureka Server 保存了注册到注册中心的所有服务实例的信息,相同的服务可以多次注册,生成多条注册信息,通过“服务名”来分组。

Feign 发起 http 请求,http 请求相关参数如:url,port等从 Ribbon 中获取。

Ribbon 定期从 Eureka 拉取服务注册列表并更新本地缓存,Ribbon 提供负载均衡能力 IRule ,根据“服务名” 获取到多个注册实例信息时通过相对应的策略进行筛选并返回一个实例信息供 Feign 进行调用。

1.2、基于 Ribbon 负载均衡策略的灰度发布

在以 Ribbon 为负载均衡客户端的服务架构中,Feign 请求发送所需要url相关信息在部署了多个实例的情况下需要借由 Ribbon 的 IRule 策略筛选出一个服务实例信息供调用。

此时就可以以 IRule 为切入点。

  • 在请求中携带表示,灰度 or 正式
  • 服务实例在注册到注册中心时,注册自定义信息,灰度 or 正式

自定义 IRule 路由规则,除了匹配 “服务名” 之外,还需要匹配 “环境”,一次达到分流的目的,实现灰度发布的能力。
02.png

二、代码实现

模仿 Spring Cloud Ribbon 默认实现 ZoneAvoidanceRule 参考:《ZoneAvoidanceRule 源码分析》

实现如下:
03.png
主要的实现:

DiscoveryServerFilterPredicateDiscoveryServerFilterRule 为上层抽象,具体实现 MetadataFilterPredicateMetadataFilterRule

  • MetadataFilterRule
  • MetadataFilterPredicate

2.1、MetadataFilterRule 关键代码

MetadataFilterRule 显示传入断言规则 MetadataFilterPredicate

  1. public class MetadataFilterRule extends DiscoveryServerFilterRule {
  2. public MetadataFilterRule() {
  3. super(new MetadataFilterPredicate());
  4. }
  5. }

具体的实现由其抽象父类 DiscoveryServerFilterRule 实现,主要的逻辑就是进行断言的组装,关键代码如下:
04.png

2.2、MetadataFilterPredicate 关键代码实现

05.png

三、测试

实例结构如下
06.png

模拟场景,当前环境部署有一套 1.7.0 的系统,1.8.0 开发并线下测试完毕,需要上到灰度去测试,测试完后并上线

1.8.0 灰度上线后进行分流

1.7.0 正式环境的版本正常对外提供API服务

1.8.0 灰度环境分流

1.8.0 正式环境分流处理

  • 如果向下兼容,1.8.0 上线后能够兼容处理旧版本的请求处理,发布中间过程 1.8.0 和 1.7.0 共存,并一起对外提供服务
  • 不想下兼容,抛出不兼容异常,app 强制进行版本更新