2020之后openfeign自定义负载均衡规则

/ 技术收藏 / 1 条评论 / 1260浏览

负载均衡的方式有很多,从客户端负载均衡,dns负载均衡,到服务器端负载均衡,均有所属的细分领域。本文仅仅探讨openfeign作为服务端的消费方,对服务提供者的负载均衡。

cloud2020版本之前,要修改openfeign默认的负载均衡方式比较简单,openfeign在负载均衡选择服务提供者时,会使用LoadBalancerClient(netflix)通过IRule这个这个接口来choose服务器,所以我们也只需要自定义一个IRule,用以替换默认的IRule实例即可,当然默认IRule也有很多实现,按需选择即可。当然我们也完全可以重新定义一个LoadBalancerClient 直接覆盖原有实例,或者在BeanPostProcessor对象后置处理器覆盖,都是可以的。spring也因为提供了这么强大的扩展性而长盛不衰。最后,不要忘了注入ioc容器。

本次重点来说2020版之后,LoadBalancerClient(netflix)也不存在,取而代之的是LoadBalancerClient(cloud),不管代码如何变,我们处理问题的思路基本不变,也就是万变不离其宗,我们一样重写 LoadBalancerClient 中的choose方法即可。不过新版的实现类只有BlockingLoadBalancerClient 这一个了。

    @Bean
    @Primary
    public LoadBalancerClient blockingLoadBalancerClient(ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory){
        LoadBalancerClient blockingLoadBalancerClient = new BlockingLoadBalancerClient(loadBalancerClientFactory){
            @Override
            public <T> ServiceInstance choose(String serviceId, Request<T> request) {
                ReactiveLoadBalancer<ServiceInstance> loadBalancer = loadBalancerClientFactory.getInstance(serviceId);
                if (loadBalancer == null) {
                    return null;
                } else {
                    List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
                    //这就是修改负载均衡策略,获取不同实例的地方
                    //下面被注释掉的return就是默认的轮询方式
                    return  instances.get(0);
//                    Response<ServiceInstance> loadBalancerResponse = (Response) Mono.from(loadBalancer.choose(request)).block();
//                    return loadBalancerResponse == null ? null : (ServiceInstance)loadBalancerResponse.getServer();
                }
            }
        };
        return  blockingLoadBalancerClient;
    };

笔者本次修改负载均衡策略主要是为了使用把用户hash到相对固定的主机上,使用jvm缓存的目的。只需要获取到用户名,计算hash,然后对服务长度取余即可。

  1. 同样的需求,一直没成功👍

    回复