灰度发布思路

灰度发布思路

1. 重写gateway 里面的 负载均衡 filter

2. 拿到对应实例的 列表数据,及元信息

3.获取请求头传过来的版本号,对比实例元信息,找到对应实例(多个可以自定义算法)我这里取第一个

响应式
public class CustomReactiveLoadBalancerClientFilter extends ReactiveLoadBalancerClientFilter 

// 核心方法
private Mono<Response<ServiceInstance>> choose(Request<RequestDataContext> lbRequest, String serviceId, Set<LoadBalancerLifecycle> supportedLifecycleProcessors) {
		ReactorLoadBalancer<ServiceInstance> loadBalancer = (ReactorLoadBalancer)this.clientFactory.getInstance(serviceId, ReactorServiceInstanceLoadBalancer.class);
		if (loadBalancer == null) {
			throw new NotFoundException("No loadbalancer available for " + serviceId);
		} else {
			supportedLifecycleProcessors.forEach((lifecycle) -> {
				lifecycle.onStart(lbRequest);
			});
			RequestDataContext requestContext = lbRequest.getContext();
			HttpHeaders headers = requestContext.getClientRequest().getHeaders();
			List<String> versions = headers.get("version");
			if(!CollectionUtils.isEmpty(versions)){
				log.info("找到 实例 {}",versions.get(0));
				List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
				for (int i = 0; i < instances.size(); i++) {
					Map<String, String> metadata = instances.get(i).getMetadata();
					String version = metadata.get("version");
					if(Objects.equals(versions.get(0),version)){
						return Mono.just(new DefaultResponse(instances.get(i)));
					}
				}
			}

			return loadBalancer.choose(lbRequest);
		}
	}
阻塞式
public class CustomLoadBalancerClientFilter extends LoadBalancerClientFilter
// 核心方法
 @Override
    protected ServiceInstance choose(ServerWebExchange exchange) {
        HttpHeaders headers = exchange.getRequest().getHeaders();
        List<String> stringList = headers.get("version");
        String version = null;
        if(!StringUtils.isEmpty(stringList)){
            version = stringList.get(0);
        }
        String host = ((URI) exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR)).getHost();
        List<ServiceInstance> instances = discoveryClient.getInstances(host);
        for (int i = 0; i < instances.size(); i++) {
            Map<String, String> metadata = instances.get(i).getMetadata();
            String metadataVersion = metadata.get("version");
            if(Objects.equals(version,metadataVersion)){
                return instances.get(i);
            }
        }


        return super.choose(exchange);
    }

元信息

思路就是这样,在重写一个 Feign 调用的 负载算法就ok了,这样就可以实现 多实例 多版本线上 测试,测试新版本没问题 在全面升级。

完善的可以参考 开源 Discovery

posted @ 2022-06-14 17:40  川流不息&  阅读(188)  评论(0编辑  收藏  举报