Spring Cloud Alibaba gateway ribbon 自定义负载均衡规则。发散灰度发布,金丝雀测试等

本文介绍了如何在Spring Cloud Gateway中实现自定义的灰度发布方案,通过header中的version字段进行服务间版本请求的路由。首先分析需求,接着详细讲解如何利用Nacos注册中心的metadata特性,重写IRule接口实现负载均衡规则,以及如何修改LoadBalancerClientFilter以处理版本信息。此外,还探讨了服务与服务间的版本请求,并提供了相关的参考资料。
摘要由CSDN通过智能技术生成

上一篇介绍了,ribbon的组件。本篇要自己写一个灰度方案。其实就是一个很简单的思维扩散。

需求

前端header请求携带version字段。路由服务根据version去需要对应版本的服务集合,进行或轮询或hash或权重的负载。请求路由到服务上,如果还要调用下游服务,也按照version规则去路由下游服务器。前端未携带版本按照后端服务最高version版本进行路由。

分析如果自己动手写一个灰度方案。需要考虑的因素有几点?

  • 服务对应的版本。key(版本号):value(对应版本号的服务集合)
  • 对应版本号的服务集合需要重新排序。
  • 重写负载均衡规则,就是ribbon的IRule方法。按照我们想要的负载规则去路由我们的请求

解决方案:

  • 利用注册中心的metadata属性元数据,让服务携带版本信息。
  • 拿到要请求的服务集合。spring cloud Alibaba nacos NamingService接口根据服务名称获取所有服务List集合,如果你使用的spring cloud 版本可以使用 ILoadBalancer 对象获取所有的服务集合
  • Instance服务里面携带了,服务注册到注册中心的自定义版本信息
  • 重写IRule负载规则。按照需求转发请求。

来写一下网关层的实现。
gateway负载规则有一个拦截器

创建负载规则的类信息GrayscaleProperties

public class GrayscaleProperties implements Serializable {
    private String version;
    private String serverName;
    private String serverGroup;
    private String active;
    private double weight = 1.0D;
}

因为gateway的特殊性LoadBalancerClientFilter过滤器主要解析lb:// 为前缀的路由规则,在通过LoadBalancerClient#choose(String) 方法获取到需要的服务实例,从而实现负载均衡。在这里我们要写自己的负载均衡就需要重新需要重写LoadBalancerClientFilter 过滤器
LoadBalancerClientFilter 介绍:次过滤器作用在url以lb开头的路由,然后利用loadBalancer来获取服务实例,构造目标requestUrl,设置到GATEWAY_REQUEST_URL_ATTR属性中,供NettyRoutingFilter使用。

GatewayLoadBalancerClientAutoConfiguration 在初始化会检测@ConditionalOnBean(LoadBalancerClient.class) 是否存在,如果存在就会加载LoadBalancerClientFilter负载过滤器

以下是源码

@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
		String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);
		//判断url 前缀 如不是lb开头的就进行下一个过滤器
		if (url == null || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
			return chain.filter(exchange);
		}
		//根据网关的原始网址。替换exchange url为 http://IP:PORT/path 路径的url
		//preserve the original url
		addOriginalRequestUrl(exchange, url);
	
		log.trace("LoadBalancerClientFilter url before: "   url);
		// 这里呢会进行调用真正的负载均衡
		final ServiceInstance instance = choose(exchange);

		if (instance == null) {
			String msg = "Unable to find instance for "   url.getHost();
			if(properties.isUse404()) {
				throw new FourOFourNotFoundException(msg);
			}
			throw new NotFoundException(msg);
		}

		URI uri = exchange.getRequest().getURI();

		// if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,
		// if the loadbalancer doesn't provide one.
		String overrideScheme = instance.isSecure() ? "https" : "http";
		if (schemePrefix != null) {
			overrideScheme = url.getScheme();
		}

		URI requestUrl = loadBalancer.reconstructURI(new DelegatingServiceInstance(instance, overrideScheme), uri);

		log.trace("LoadBalancerClientFilter url chosen: "   requestUrl);
		exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
		return chain.filter(exchange);
	}
	。。。。
	// 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值