Ribbon中的IRule

负载均衡器Ribbon中的IRule负责选择什么样的负载均衡算法

源码中IRule的接口

package com.netflix.loadbalancer;

/**
 - Interface that defines a "Rule" for a LoadBalancer. A Rule can be thought of
 - as a Strategy for loadbalacing. Well known loadbalancing strategies include
 - Round Robin, Response Time based etc.
 - 
 - @author stonse
 - 
 */
public interface IRule{
    /*
     * choose one alive server from lb.allServers or
     * lb.upServers according to key
     * 
     * @return choosen Server object. NULL is returned if none
     *  server is available 
     */

    public Server choose(Object key);

    public void setLoadBalancer(ILoadBalancer lb);

    public ILoadBalancer getLoadBalancer();    
}

该接口的实现类有
这里写图片描述

  • RoundRobinRule:轮询(默认)
  • RandomRule:随机
  • RetryRule:重试(先按照轮询规则获取服务,如果获取服务失败则在指定时间内进行重试)

如果修改规则为源码中的其他规则吗可以在配置类中注入相应的Bean

demo

package com.mark.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.springcloud.MyRandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by Choisaaaa on 2018/7/9.
 * 自定义的轮询算法的配置类
 */
@Configuration
public class MyRuleConfig {

    @Bean //修改轮询规则为随机
    public IRule iRule(){
        return new RandomRule();
    }
}

随机规则RandomRule源码中的choose方法

    /**
     * Randomly choose from all living servers
     */
    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) {
                /*
                 * No servers. End regardless of pass, because subsequent passes
                 * only get more restrictive.
                 */
                return null;
            }

            int index = rand.nextInt(serverCount);
            server = upList.get(index);//从存活的列表中获取server

            if (server == null) {//如果获取到的服务实例为空
                /*
                 * The only time this should happen is if the server list were
                 * somehow trimmed. This is a transient condition. Retry after
                 * yielding.
                 */
                Thread.yield();//线程让步
                continue;//调到下一次循环(server == null)会为真继续进入while循环
            }

            if (server.isAlive()) { //如果服务实例是存活的则返回该服务实例
                return (server);
            }

            // Shouldn't actually happen.. but must be transient or a bug.
            server = null;
            Thread.yield();
        }

        return server;

    }

编写自定义的轮询规则

1.编写自定义的轮写规则类(该类不能和主程序类在同一层目录结构或者在子包下)
demo

package com.springcloud;

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

import java.util.List;
import java.util.Random;

/**
 * Created by Choisaaaa on 2018/7/9.
 * 自定义随机算法
 *
 * 一个服务实例server 用3次  在轮询选择下一个server
 */
public class MyRandomRule extends AbstractLoadBalancerRule {


    Random rand;

    public MyRandomRule() {
        rand = new Random();
    }

    /**
     * Randomly choose from all living servers
     */
    public Server choose(ILoadBalancer lb, Object key) {
    //重写该方法
    }

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

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

    }
}

2.编写配置类将自定义的规则类注入到IOC容器中
demo

package com.mark.config;

import com.netflix.loadbalancer.IRule;
import com.springcloud.MyRandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by Choisaaaa on 2018/7/9.
 * 自定义的轮询算法的配置类
 */
@Configuration
public class MyRuleConfig {

    @Bean //注入自定义的负载均衡的算法
    public IRule iRule(){
        return new MyRandomRule();
    }
}

3.修改主程序类
@RibbonClient(name = “PROVIDERPRODUCT”,configuration = MyRuleConfig.class)

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
//为服务PROVIDERPRODUCT指定自定义的负载均衡算法
@RibbonClient(name = "PROVIDERPRODUCT",configuration = MyRuleConfig.class)
public class ConsumerApplication {

猜你喜欢

转载自blog.csdn.net/ycd500756/article/details/80975410