自定义动态IRule进行路由转发

gateway的负载均衡以及feign服务之间的调用或者RestTemplate请求,都可以使用自定义IRule规则进行路由转发。

自定义IRule

  1. 固定IRule:将IRule的一个实现类注入到spring容器中

    @Configuration 
    public class MyIRuleConfig {
          
           
    	@Bean
    	public IRule myIRule() {
          
          
    		return new RandomRule();
    	}
    }
    

    注意: 这个自定义配置类不能放在@ComponentScan所扫描的当前包及其子包下

  2. 固定IRule: 使用注解@RibbonClient;

    // configuration 属性可以包含构成客户端的部分的重写@Bean定义,例如ILoadBalancer、ServerListFilter、IRule。
    @RibbonClient(name = "test-client", configuration = RandomRule.class)
    
  3. 可以动态调整的IRule:需要继承ribbonSpringClientFactory类并且创建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原理:

  1. gateway路由转发:

    本质上,还是使用请求过滤器,gateway用的是LoadBalancerClientFilter,在这里的filter方法,会在获取ServiceInstance时调用RibbonLoadBalancerClient的choose方法选择一个服务,在choose方法中,调用了getServer()getServer()调用getLoadBalancer(),使用SpringClientFactorybean对象获取ILoadBalancer,所以我们要继承ribbon的SpringClientFactory类并且创建bean对象,子类里面要重写getLoadBalancer,给ILoadBalancer设置自定义的IRule路由规则,这样就能自定义路由转发;
    在这里插入图片描述
    在这里插入图片描述

  2. openfeign

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

在这里插入图片描述
在这里插入图片描述

  1. RestTemplate调用:

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

猜你喜欢

转载自blog.csdn.net/blood_Z/article/details/128660574