灰度发布思路

2022-06-14  本文已影响0人  川流不息attitude

灰度发布思路

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);
    }

元信息

image.png

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

完善的可以参考 开源 Discovery

上一篇 下一篇

猜你喜欢

热点阅读