Ribbon之自定义负载均衡算法

官网指出:

这个自定义的类不能放在@ComponentScan所扫描的当前包以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是我们达不到特殊化指定的目的了。推荐在springboot主程序扫描的包范围之外进行自定义配置类。

代码实现如下

配置类不应该在SpringBoot的包路径下通过@RibbonClient 注解加载:

package com.dsx.rule;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RetryRule;

@Configuration
public class MySelfRule {
	//在这里选择负载均衡算法,
	@Bean
	public IRule myRule() {
		return new MyRandomRule();//默认轮询,此处是自定义的算法
		
	}
}

自定义负载均衡算法

package com.dsx.rule;

import java.util.List;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

public class MyRandomRule extends AbstractLoadBalancerRule{
	//每个服务访问5次,换下一个服务(2个)
	//被调用的次数
	private int total=0;
	//当前是谁在调用服务
	private int currentIndex = 0;
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        Server server = null;

        while (server == null) {
            if (Thread.interrupted()) {
                return null;
            }
            List<Server> upList = lb.getReachableServers();//获得活着的服务
            //获得全部的服务
            List<Server> allList = lb.getAllServers();

            int serverCount = allList.size();
            if (serverCount == 0) {
               
                return null;
            }

            //自定义算法     
	       if(total <5) {
	    	   server = upList.get(currentIndex);
	    	   total++;
	       }else {
	    	   total = 0;
	    	   currentIndex++;
	    	   if(currentIndex > upList.size()) {
	    		   currentIndex = 0;
	    	   }
	    	   //从存活着的服务中,获取指定服务来进行操作
	    	   server = upList.get(currentIndex);
	       }
            if (server == null) {
                Thread.yield();
                continue;
            }

            if (server.isAlive()) {
                return (server);
            }
            server = null;
            Thread.yield();
        }

        return server;
    }
	    //生成区间随机数
		protected int chooseRandomInt(int serverCount) {
		// 从活着的服务中,随机获取一个
		return ThreadLocalRandom.current().nextInt(serverCount);
	}

		@Override
		public Server choose(Object key) {
			return choose(getLoadBalancer(), key);
		}

		@Override
		public void initWithNiwsConfig(IClientConfig clientConfig) {
			// TODO Auto-generated method stub
			
		}

}

启动类

package com.dsx;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;

import com.dsx.rule.MySelfRule;

@EnableEurekaClient  //向服务注册中心进行注册
@SpringBootApplication
@RibbonClient(name="MICROSERVICE-PRODUCT",configuration=MySelfRule.class)
public class ConsumerApp {
	public static void main(String[] args) {
		SpringApplication.run(ConsumerApp.class, args);
	}
}

启动后访问实现了简单的自定义的负载均衡算法。

注意:

@RibbonClient(name = "MICROSERVICE-PRODUCT", configuration = MySelfRule.class)

name指定针对哪个服务 进行负载均衡,而configuration指定负载均衡的算法具体实现类

自定义Ribbon Client的主要作用就是使用自定义配置替代Ribbon默认的负载均衡策略,

发布了132 篇原创文章 · 获赞 1 · 访问量 7278

猜你喜欢

转载自blog.csdn.net/duan196_118/article/details/104345908