• Spring Cloud Gateway(七):路由谓词工厂WeightRoutePredicateFactory


    本文基于 spring cloud gateway 2.0.1 接上文

    5、基于路由权重(weigth)的谓词工厂

    Spring Cloud Gateway 提供了基于路由权重的断言工厂,配置时指定分组和权重值 即可。WeightRoutePredicateFactory 实现了路由权重的功能,按照路由权重选择 同一个分组中的路由。

    spring:
      cloud:
        gateway:
          locator:
            enabled: true
          routes:
            -id: weight_route1
              uri: http://www.baidu1.com
              order: 6000
              predicates:
              -Weight= group3, 1
              -Path=/ weight/**
              filters:
              -StripPrefix= 2
            -id: weight_route2
              uri: http://www.baidu2.com
              order: 6000
              predicates: 
              -Path=/ weight/** 
              -Weight= group3, 9 
              filters: 
              -StripPrefix=1
    
    

    如上配置了两个对于 / weight/** 路径转发的路由定义,这两个路由是同一个权重分组,且 weight_ route1 权重为 1, weight_ route2 权重为9。 对于10个访问/ weight/** 路径的请求来说,将会有9个路由到 weight_ route2,1个路由到 weight_ route1。

    5.1、WeightRoutePredicateFactory 权重算法实现过程

    weight_ route1: group3, 1 
    weight_ route2: group3, 9
    

    实现过程为:

    1)构造 weights(group3)数组:weights=[ 1, 9]

    2)normalize: weights= weights/ sum( weights)=[ 0. 1, 0. 9]
    3)计算区间范围: ranges= weights. collect( 0,( s, w)-> s+ w)=[ 0, 0. 1, 1. 0]

    4)生成 随机数: r= random()

    5)搜索随机数所在的区间: i= integer s. t. r>= ranges[ i]&& r< ranges[ i+ 1]

    6)选择相应的路由: routes[ i]

    网关应用服务在启动时会发布 WeightDefinedEvent,在 WeightCalculatorWebFilter 过滤器中定义了该时间监听器,当接收到时间 WeightDefinedEvent 时,会自动添加 WeightConfig 到权重配置中。请求在经过 WeightCalculatorWebFilter 时会 生成 一个 随机数, 根据随机数所在的区间选择对应分组的路由。

    // WeightRoutePredicateFactory.java

    @Override
    	public Predicate<ServerWebExchange> apply(Config config) {
            List<IpSubnetFilterRule> sources = convert(config.sources);
    
    		return exchange -> {
    			InetSocketAddress remoteAddress = config.remoteAddressResolver.resolve(exchange);
    			if (remoteAddress != null) {
    				String hostAddress = remoteAddress.getAddress().getHostAddress();
    				String host = exchange.getRequest().getURI().getHost();
    
    				if (log.isDebugEnabled() && !hostAddress.equals(host)) {
    					log.debug("Remote addresses didn't match " + hostAddress + " != " + host);
    				}
    
    				for (IpSubnetFilterRule source : sources) {
    					if (source.matches(remoteAddress)) {
    						return true;
    					}
    				}
    			}
    
    			return false;
    		};
    	}
    

    当应用到配置的路由断言 WeightRoutePredicate 时,会根据 ServerWebExchange 中的 WEIGHT_ ATTR 值,判断当前的 routeId 与对应分组的 routeId 是否一致。

  • 相关阅读:
    linux eclipse cdt make error 127
    centos 安装网络错误
    c++ string 结束符‘00’
    北京市工资交税情况
    gprof参数说明及常见错误
    【转】Eclipse Plugin 在 Console上打印出message
    C++做client Java做客户端传送数据
    word统计章节字数
    【转】Profiling application LLC cache misses under Linux using Perf Events
    【转】eclipse插件开发,调试运行,导出与安装
  • 原文地址:https://www.cnblogs.com/liukaifeng/p/10055866.html
Copyright © 2020-2023  润新知