1. 程式人生 > 實用技巧 >Ribbon 負載均衡自定義演算法

Ribbon 負載均衡自定義演算法

自定義負載均衡

IRule介面介紹

  • com.netflix.loadbalancer.IRule 是自定義負載均衡的演算法實現類
  • 原始碼
/**
 * 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();    
}
  • 實現類介紹
AvailabilityFilteringRule: 先過濾掉跳閘,訪問故障的服務,再對剩下的服務進行輪詢
RoundRobinRule:輪詢排程,預設的
RandomRule:隨機排程
WeightedResponseTimeRule:根據權重排程
RetryRule:會先輪詢獲取服務,如果獲取失敗,則會在一定的時間內進行重試

開始

    1. 在主啟動類上級,建立配置檔案,不能在同級,同級會被掃描到
    1. 在啟動類上使用註解,指向自定義的演算法配置類
@SpringBootApplication
@EnableEurekaClient //為Eureka客戶端
//微服務啟動時就會去載入我們的Ribbon配置類
@RibbonClient(name = "provider-person-8001",configuration = NumberRule.class)
public class PersonConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(PersonConsumerApplication.class,args);
    }
}
  • 3.程式碼
  • 和Ribbon同包下的配置類
@Configuration
public class ZZNumberConfig {
    @Bean
    public NumberRule numberRule(){
        return new NumberRule();
    }
}
  • 自定義演算法的負載均衡實現類,參考自RoundRobinRule
public class NumberRule extends AbstractLoadBalancerRule {

    private static Logger log = LoggerFactory.getLogger(RoundRobinRule.class);

    private int total = 0;//總數
    private int cunnentIndex = 0;//當前索引,指向那個服務


    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        }

        Server server = null;
        int count = 0;
        while (server == null && count++ < 10) {
            List<Server> reachableServers = lb.getReachableServers(); //還活著的服務
            List<Server> allServers = lb.getAllServers(); //所有得服務
            int upCount = reachableServers.size(); //活著的數量
            int serverCount = allServers.size(); //所有服務的數量

            if ((upCount == 0) || (serverCount == 0)) {
                log.warn("No up servers available from load balancer: " + lb);
                return null;
            }

            //總數小於還活著的數量
           if(total < 3){
               server = reachableServers.get(cunnentIndex);
               total++;
           }else {
               total =0;
               cunnentIndex++;
               if(cunnentIndex >=  reachableServers.size()){
                   cunnentIndex = 0;
               }
               server = reachableServers.get(cunnentIndex);
           }

            if (server == null) {
                /* Transient. */
                Thread.yield();
                continue;
            }

            if (server.isAlive() && (server.isReadyToServe())) {
                return (server);
            }

            // Next.
            server = null;
        }

        if (count >= 10) {
            log.warn("No available alive servers after 10 tries from load balancer: "
                    + lb);
        }
        return server;
    }



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

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }
}