一 灰度发布
灰度发布也叫金丝雀发布,起源是,矿井工人发现,金丝雀对瓦斯气体很敏感,矿工会在下井之前,先放一只金丝雀到井中,如果金丝雀不叫了,就代表瓦斯浓度高.
在灰度发布开始后,先启动一个新版本应用,但是并不直接将流量切过来,而是测试人员对新版本进行线上测试,启动的这个新版本应用,就是我们的金丝雀。如果没有问题,那么可以将少量的用户流量导入到新版本上,然后再对新版本做运行状态观察,收集各种运行时数据,如果此时对新旧版本做各种数据对比,就是所谓的A/B测试。
当确认新版本运行良好后,再逐步将更多的流量导入到新版本上,在此期间,还可以不断地调整新旧两个版本的运行的服务器副本数量,以使得新版本能够承受越来越大的流量压力。直到将100%的流量都切换到新版本上,最后关闭剩下的老版本服务,完成灰度发布。
如果在灰度发布过程中(灰度期)发现了新版本有问题,就应该立即将流量切回老版本上,这样,就会将负面影响控制在最小范围内。
二 实现思路
2.1 基本思路
Spring Cloud LoadBalancer是一个客户端负载均衡器,类似于Ribbon,但是由于Ribbon已经进入维护模式,并且Ribbon 2并不与Ribbon 1相互兼容,所以Spring Cloud全家桶在Spring Cloud Commons项目中,添加了Spring cloud Loadbalancer作为新的负载均衡器,并且做了向前兼容;
本文主要是基于Spring Cloud LoadBalancer,重写Spring Cloud LoadBalancer默认的客户端负载均衡器,实现灰度均衡
我们可以看到Spring Cloud LoadBalancer提供的负载均衡策略比较少,内置轮询、随机的负载均衡策略,默认轮询策略,本文主要覆写轮询策略的解析请求的请求头获得当前请求的版本后,从nacos匹配到相对应的版本实例实现灰度版本的负载均衡.
2.2 代码实现
2.2.1 自定义灰度负载均衡策略
重写轮询策略,实现自定义的灰度策略
自定义灰度策略继承轮询策略,重写choose方法,解析当前请求头中版本号与nacos元数据中的版本号比对,匹配后返回相应的服务实例.
/**
* 自定义灰度校验策略
* @author likun
* @date 2022年06月23日 16:08
*/
@Slf4j
public class GrayRoundRobinLoadBalancer extends RoundRobinLoadBalancer {
final String serviceId;
ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
public GrayRoundRobinLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId) {
super(serviceInstanceListSupplierProvider, serviceId);
this.serviceId=serviceId;
this.serviceInstanceListSupplierProvider=serviceInstanceListSupplierProvider;
}
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
//从当前请求头中获得请求的版本号
ServiceInstanceListSupplier supplier = (ServiceInstanceListSupplier)this.serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get(request).next().map((serviceInstances) -> this.getInstanceResponse(request, serviceInstances));
}
public Response<ServiceInstance>