美文网首页
SpringCloud灰度发布

SpringCloud灰度发布

作者: 知止9528 | 来源:发表于2021-01-24 09:54 被阅读0次

    一: 调用链分析

    请求==>网关==>服务Resttemplate调用==>服务
    请求==>网关==>服务Fegin调用==>服务

    无论是通过Resttemplate还是Fegin的方式进行服务间的调用,他们都会从Ribbon选择一个服务实例返回


    二:调用链详细步骤

    1. 用户请求首先到达Nginx然后转发到网关,此时网关拦截器会根据用户携带请求token解析出对应的userId

    2. 网关从配置中心拉取灰度用户列表,然后根据灰度用户策略判断该用户是否是灰度用户。如是,则给该请求添加请求头线程变量添加信息version=xxx;若不是,则不做任何处理放行

    3. 在网关拦截器执行完毕后,网关在进行转发请求时会通过负载均衡器Ribbon。

    4. 负载均衡Ribbon被重写。当请求到达时候,Ribbon会取出网关存入线程变量值
      version
      。于此同时,Ribbon还会取出所有缓存的服务列表(定期从eureka刷新获取最新列表)及其该服务的metadata-map信息。然后取出服务metadata-map的version信息与线程变量version进行判断对比,若值一直则选择该服务作为返回。若所有服务列表的version信息与之不匹配,则返回null,此时Ribbon选取不到对应的服务则会报错!

    5. 当服务为非灰度服务,即没有version信息时,此时Ribbon会收集所有非灰度服务列表,然后利用Ribbon默认的规则从这些非灰度服务列表中返回一个服务。

    6. 网关通过Ribbon将请求转发到consumer服务后,可能还会通过fegin或resttemplate调用其他服务,如provider服务。但是无论是通过fegin还是resttemplate,他们最后在选取服务转发的时候都会通过Ribbon。

    7. 那么在通过fegin或resttemplate调用另外一个服务的时候需要设置一个拦截器,将请求头version=xxx给带上,然后存入线程变量。

    8. 在经过fegin或resttemplate 的拦截器后最后会到Ribbon,Ribbon会从线程变量里面取出version信息。然后重复步骤(4)和(5)


    小结

    1. 将注册中心的灰度服务打上标识
    eureka可以使用eureka.instance.metadata-map配置
    备注:
    Eureka的元数据有两种,分别为标准元数据和自定义元数据。
    标准元数据:主机名、IP地址、端口号、状态页和健康检查等信息,这些信息都会被发布在服务注册表中,用于服务之间的调用。
    自定义元数据:自定义元数据可以使用eureka.instance.metadata-map配置,这些元数据可以在远程客户端中访问,但是一般不会改变客户端的行为,除非客户端知道该元数据的含义
    

    1. 请求到达网关时获取灰度用户,对应的灰度用户在请求头里设置上灰度标识
    SpringGateWay过滤器GlobalFilter 
    Dubbo过滤器Filter
    Zuul过滤器ZuulFilter 
    

    1. 路由或者负载均衡器获取服务列时,根据灰度标识,获取对应的服务
    resttemplate拦截器ClientHttpRequestInterceptor
    fegin拦截器RequestInterceptor
    

    Ribbon自定义负载均衡ZoneAvoidanceRule
    Ribbon详细扩展点可参考前面文章

    public class GrayMetadataRule extends ZoneAvoidanceRule {
       // 略....
        @Override
        public Server choose(Object key) {
            //1.从线程变量获取请求头里获取version信息
            String version = xxx;
            
           //2.获取服务实例列表
            List<Server> serverList = this.getPredicate().getEligibleServers(this.getLoadBalancer().getAllServers(), key);
            
           //3.循环serverList,选择version匹配的服务并返回
                    for (Server server : serverList) {
                Map<String, String> metadata = ((DiscoveryEnabledServer) server).getInstanceInfo().getMetadata();
    
                String metaVersion = metadata.get("version);
                if (!StringUtils.isEmpty(metaVersion)) {
                    if (metaVersion.equals(hystrixVer)) {
                        return server;
                    }
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:SpringCloud灰度发布

          本文链接:https://www.haomeiwen.com/subject/buacaktx.html