Ribbon自定義負載均衡策略算法Feign和RestTemplate


原文鏈接:https://blog.csdn.net/weixin_40991408/article/details/103921299

一. Ribbon 負載均衡策略介紹

看圖,不解釋
在這里插入圖片描述
默認 輪詢

二. Feign 更改負載均衡策略

項目用 eureka-feign-hystrix-client,參考文章

feign 更改負載就均衡策略 只要在配置文件 application.yml 配置就行,代碼如下:

server:
  port: 8767

spring:
  #配置程序名為eureka-feign-hystrix-client
  application:
    name: eureka-feign-hystrix-client

eureka:
  client:
    #服務注冊地址
    serviceUrl:
      #注意: Eureka Server 的注冊地址
      #將服務提供者注冊到三個Eureka Server中去
      #defaultZone: http://peer1:8001/eureka/,http://peer2:8002/eureka/,http://peer3:8003/eureka/
      #defaultZone: http://peer1:8001/eureka/
      defaultZone: http://localhost:8761/eureka/

feign:
  hystrix:
    enabled: true  #開啟 Hystrix 功能

logging:
  level:
    #feign 接口類的路徑(這個配置表示的意思是,在調用 FeignHystrixInter 接口時做debug日志的輸出。)
    com:
      example:
        eurekafeignhystrixclient:
          inter:
            FeignHystrixInter: debug
            # 如何配置多個 Feign 接口類 的 調用日志
            # FeignHystrixInter2: debug
            # FeignHystrixInter3: debug
            # FeignHystrixInter4: debug

# Feign 如何結合 Ribbon 切換負載均衡策略算法
eureka-client: # eureka-client 表示作用到哪個微服務
  ribbon:
    # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置規則 隨機
    # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #配置規則 輪詢
    # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule #配置規則 重試
    # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule #配置規則 響應時間權重
    # 我們也可以指定為其他策略,包括我們自己定義的,只要把相應的包路徑寫到這即可。
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

    # ConnectTimeout: 500 #請求連接超時時間
    # ReadTimeout: 1000 #請求處理的超時時間
    # OkToRetryOnAllOperations: true #對所有請求都進行重試
    # MaxAutoRetriesNextServer: 2 #切換實例的重試次數
    # MaxAutoRetries: 1 #對當前實例的重試次數

 

 

三. RestTemplate 中更改負載均衡策略算法

項目用 eureka-ribbon-hystrix-client,參考文章

RestTemplate 更改負載就均衡策略 只要在Ribbon配置類 RibbonConfig 添加代碼即可,代碼如下:

package com.example.eurekaribbonhystrixclient.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * 如何將RestTemplate 和 Ribbon 相結合進行負載均衡?
 * 只需要在程序的IOC容器中注入一個 RestTemplate 的 Bean,並在這個 Bean 上加上 @LoadBalanced 注解(負載均衡注解)
 * 此時 RestTemplate 就結合 Ribbon 開啟了負載均衡功能
 *
 */

@Configuration
public class RibbonConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    /**
     * 更改 負載均衡策略算法
     * RandomRule #配置規則 隨機
     * RoundRobinRule #配置規則 輪詢
     * RetryRule #配置規則 重試
     * WeightedResponseTimeRule #配置規則 響應時間權重
     * 也可以自定義負載均衡策略的類
     * @return
     */
    @Bean
    public IRule myRule(){
        return new RandomRule();
    }
}

 

 

四.自定義負載均衡策略的類

定義 MyCustomRule 類 繼承 AbstractLoadBalancerRule 類,重寫父類方法。
例如:要求每台服務器被調用5次才能輪詢下一個,也就是說以前每台機器一次,現在每台機器5次。代碼如下:

package com.example.eurekaribbonhystrixclient.rule;

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.concurrent.ThreadLocalRandom;

/**
 * 要求每台服務器被調用5次才能輪詢下一個,也就是說以前每台機器一次,現在每台機器5次。
 */
public class MyCustomRule extends AbstractLoadBalancerRule {
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

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

    /**
     * Randomly choose from all living servers
     */
    //@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
    //從服務清單中隨機選擇一個服務實例
    @SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        Server server = null;

        int total = 0; // 總共被調用的次數,目前要求每台被調用5次
        int currentIndex = 0; // 當前提供服務的機器號

        while (server == null) {
            if (Thread.interrupted()) {
                return null;
            }
            //負載均衡來獲得可用實例列表upList和allList
            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;
            }
            if (total < 5) {
                server = upList.get(currentIndex);
                total++;
            } else {
                total = 0;
                currentIndex++;
                if (currentIndex >= upList.size()) {
                    currentIndex = 0;
                }
            }
            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;
            }
            if (server.isAlive()) {
                return (server);
            }
            // Shouldn't actually happen.. but must be transient or a bug.
            server = null;
            Thread.yield();
        }
        //正常情況下,每次都應該可以選擇一個服務實例
        return server;
    }


    //隨機獲取一個隨機數
    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }

}

 

 

在Feign中 ,在配置文件application.yml 配置自定義的策略,如圖所示:

在這里插入圖片描述

在RestTemplate,配置自定義的策略,代碼如下:

package com.example.eurekaribbonhystrixclient.config;


import com.example.eurekaribbonhystrixclient.rule.MyCustomRule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * 如何將RestTemplate 和 Ribbon 相結合進行負載均衡?
 * 只需要在程序的IOC容器中注入一個 RestTemplate 的 Bean,並在這個 Bean 上加上 @LoadBalanced 注解(負載均衡注解)
 * 此時 RestTemplate 就結合 Ribbon 開啟了負載均衡功能
 *
 */

@Configuration
public class RibbonConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    /**
     * 更改 負載均衡策略算法
     * RandomRule #配置規則 隨機
     * RoundRobinRule #配置規則 輪詢
     * RetryRule #配置規則 重試
     * WeightedResponseTimeRule #配置規則 響應時間權重
     * 也可以自定義負載均衡策略的類
     * @return
     */
    @Bean
    public IRule myRule(){
        return new MyCustomRule();//自定義的Rule
        //return new RandomRule();
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM