gateway的负载均衡以及feign服务之间的调用或者RestTemplate请求,都可以使用自定义IRule规则进行路由转发。
自定义IRule
 
-  
固定
IRule:将IRule的一个实现类注入到spring容器中@Configuration public class MyIRuleConfig { @Bean public IRule myIRule() { return new RandomRule(); } }注意: 这个自定义配置类不能放在
@ComponentScan所扫描的当前包及其子包下 -  
固定
IRule: 使用注解@RibbonClient;// configuration 属性可以包含构成客户端的部分的重写@Bean定义,例如ILoadBalancer、ServerListFilter、IRule。 @RibbonClient(name = "test-client", configuration = RandomRule.class) -  
可以动态调整的
IRule:需要继承ribbon的SpringClientFactory类并且创建bean对象,里面要重写getLoadBalancer,给ILoadBalancer设置自定义的IRule路由规则。@Slf4j public class MySpringClientFactory extends SpringClientFactory { @Override public ILoadBalancer getLoadBalancer(String name) { ILoadBalancer instance = this.getInstance(name, ILoadBalancer.class); if (instance instanceof DynamicServerListLoadBalancer) { DynamicServerListLoadBalancer dsbl = (DynamicServerListLoadBalancer) instance; try { // 伪代码,这里实际应该使用你自己定义的 IRule,同时,这里可以进行动态调整,因为每一次进行请求时,rabbon都会调用这个 getLoadBalancer()方法。 IRule iRule = new RandomRule(); dsbl.setRule(iRule); return dsbl; } catch (Exception e) { logger.error("ribbon获取负载均衡器实例异常", e); } } return instance; } } 
动态设置IRule原理:
 
-  
gateway路由转发:本质上,还是使用请求过滤器,gateway用的是
LoadBalancerClientFilter,在这里的filter方法,会在获取ServiceInstance时调用RibbonLoadBalancerClient的choose方法选择一个服务,在choose方法中,调用了getServer(),getServer()调用getLoadBalancer(),使用SpringClientFactorybean对象获取ILoadBalancer,所以我们要继承ribbon的SpringClientFactory类并且创建bean对象,子类里面要重写getLoadBalancer,给ILoadBalancer设置自定义的IRule路由规则,这样就能自定义路由转发;


 -  
openfeign:会调用LoadBalancerFeignClient.lbClient()创建FeignLoadBalancer对象,这里调用CachingSpringLoadBalancerFactory.create(),先去类的本地缓存map变量cache中获取,FeignLoadBalancer没有就创建,创建时会加载ILoadBalancer,ILoadBalancer由
SpringClientFactory的getLoadBalancer获取(所以重写getLoadBalancer()方法,能设置ILoadBalancer的权重规则IRule),最后还是构造HttpURLConnection来发送http请求。 

 
-  
RestTemplate调用:增加
@LoadBalanced注解之后,就会在restTemplate里面 通过restTemplate.setInterceptors放入给RestTemplate 增加LoadBalancerInterceptor拦截器,在拦截器中使用LoadBalancerClient的实现类RibbonLoadBalancerClient.execute()方法进行负载均衡调用。所以这里也是继承ribbon的SpringClientFactory类并且创建bean对象,里面要重写getLoadBalancer,给ILoadBalancer设置自定义的IRule路由规则。




 









![[蓝桥杯 2017 省 B] k 倍区间(前缀和枚举/数论优化)](https://img-blog.csdnimg.cn/20200323125755407.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3RoZV9aRUQ=,size_16,color_FFFFFF,t_70)









