微服务负载均衡组件-Ribbon

什么是Ribbon

Ribbon是Netflix发布的开源项目,其主要功能是提供客户端侧负载均衡算法。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。Ribbon会自动的帮助你基于某种规则(如轮询,随机等)去连接这些机器,用时,Ribbon也支持自定义的负载均衡算法

在SpirngCloud中,Ribbon利用从Eureka中读取到的服务提供者列表信息,在调用服务节点提供服务时,基于内置的负载均衡算法,进行服务请求。

Ribbo和Nginx区别

一般实现负载均衡,会有俩个选择,客户端负载均衡和服务端的负载均衡

Nginx是服务端负载均衡,负载均衡的策略算法是在服务端实现的。

Ribbon是客户端负载均衡,负载均衡算法是由调用者本身进行维护的。

策略

Ribbon内置了多种负载均衡策略,内部负责复杂均衡的顶级接口为

com.netflix.loadbalancer.IRule;

com.netflix.loadbalancer.RoundRobinRule;轮询策略
com.netflix.loadbalabcer.RandomRule; 随机策略;
com.netflix.loadbalancer.BestAvailableRule;  最佳可用策略

用法

1.添加pom文件

        <!--Ribbon-->
<!--        <dependency>-->
<!--            <groupId>org.springframework.cloud</groupId>-->
<!--            <artifactId>spring-cloud-starter-ribbon</artifactId>-->
<!--            <version>1.4.6.RELEASE</version>-->
<!--        </dependency>-->
         
         <!--自带有ribbon-->
  <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-   client</artifactId>
   </dependency>

2. 添加注解

 @Bean
    @LoadBalanced //Ribbon
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

自定义ribbon

1. 重写方法


public class KuangRandomRule extends AbstractLoadBalancerRule {

    //每个服务,访问5次~,换下一个服务(3个)

    // total=0, 默认=0,如果=5,我们指向下一个服务节点
    // index=0,默认0,如果total=5,index+1,

    private int total = 0; //被调用的次数
    private int currentIndex = 0; //当前是谁在提供服务~
   //@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
   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;
           }

// int index = chooseRandomInt(serverCount); //生成区间随机数
// server = upList.get(index); //从活着的服务中,随机获取一个~

       //-=========================================================

           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
   		
   	}
   }


   2. 注入进去

      ````java
       @Bean
          public IRule myRule(){
              return new RoundRobinRule(); //默认是轮询,现在我们定义为~ KuangRandomRule
          }

:一定要写在主配置外面,不然会被componentscan扫描到。否则,它由所有@RibbonClients共享。如果您使用@ComponentScan(或@SpringBootApplication),则需要采取措施避免将其包括在内(例如,可以将其放在单独的,不重叠的程序包中,或指定要在@ComponentScan)。

posted @ 2020-08-08 11:34  杰的博客#  阅读(514)  评论(0编辑  收藏  举报