SpringCloudAlibaba - 整合 Ribbon 實現負載均衡


前言

Ribbon是一個Netflix開源的客戶端側負載均衡器,其提供了豐富的負載均衡算法,服務消費者集成Ribbon后,Ribbon會自動從Nacos Server獲取想要調用的服務的地址列表,通過負載均衡算法計算出一個實例交給RestTemplate調用


注:Spring Cloud 2020 已移除對 Ribbon 的支持,相應的,Spring Cloud 2021 版本 Nacos 中 也刪除了Ribbon 的 jar 包,實現時需要注意版本依賴關系


環境

Spring Cloud Hoxton.SR9 + Spring Cloud Alibaba 2.2.6.RELEASE


簡單示例

  • spring-cloud-starter-alibaba-nacos-discovery中默認包含Ribbon,所以不需要添加依賴

在這里插入圖片描述


這里的示例代碼是內容中心(content-center)通過調用用戶中心(user-center)的兩個實例看是否實現負載均衡


user-center

  • TestController.java
@RestController
@Slf4j
public class TestController {

    @GetMapping("/test/{name}")
    public String test(@PathVariable String name) {
    	log.info("請求...");
        return "hello " + name;
    }

}
  • 用戶中心以80818082端口啟動

在這里插入圖片描述


在這里插入圖片描述



content-center

  • 啟動類
/**
 * @LoadBalanced 為RestTemplate 整合Ribbon
 */
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}
  • TestController.java
@RestController
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TestController {

	private final RestTemplate restTemplate;

    /**
     * 整合Ribbon
     * @return
     */
    @GetMapping("test3")
    public String test3() {
        /**
         * RestTemplate 請求時,ribbon會把user-center轉換成用戶中心在Nacos上的地址,
         * 進行負載均衡算法計算出一個實例去請求
         */
        return restTemplate.getForObject(
                "http://user-center/test/{name}",
                String.class,
                "Coisini"
        );
    }
}

測試

  • 訪問接口測試,可以發現Ribbon以輪詢的方式實現負載均衡

在這里插入圖片描述
在這里插入圖片描述


Ribbon 的組成和默認的負載均衡規則

Ribbon 的組成

  • Ribbon為所有的組件提供了接口,如果對默認值不滿意,可以實現這些接口進行二次開發
接口 作用 默認值
IClientConfig 讀取配置 DefaultClientConfigImpl
IRule 負載均衡規則,選擇實例 ZoneAvoidanceRule
IPing 篩選掉ping不通的實例 DummyPing
ServerList< Server> 交給Ribbon的實例列表 Ribbon:ConfigurationBasedServerList
Spring Cloud Alibaba: NacosServerList
ServerListFilter< Server> 過濾掉不符合條件的實例 ZonePreferenceServerListFilter
ILoadBalancer Ribbon的入口 ZoneAwareLoadBalancer
ServerListUpdater 更新交給Ribbon的List的策略 PollingServerListUpdater

Ribbon 默認的負載均衡規則

  • Ribbon默認的負載均衡規則是ZoneAvoidanceRule,在沒有zone的情況下默認是輪詢
  • Ribbon內置的負載均衡規則如下
規則名稱 特點
AvailabilityFilteringRule 過濾掉一直連接失敗的被標記為circuit tripped的后端Server,並過濾掉那些高並發的后端Server或者使用一個AvailabilityPredicate來包含過濾server的邏輯,其實就是檢查status里記錄的各個Server的運行狀態
BestAvailableRule 選擇一個最小的並發請求的Server,逐個考察Server,如果Server被tripped了,則跳過
RandomRule 隨機選擇一個Server
ResponseTimeWeightedRule 已廢棄,作用同WeightedResponseTimeRule
RetryRule 對選定的負載均衡策略機上重試機制,在同一個配置時間段內當選擇Server不成功,則一直嘗試使用subRule的方式選擇一個可用的Server
RoundRobinRule 輪詢選擇,輪詢index,選擇index對應位置的Server
WeightedResponseTimeRule 根據響應時間加權,響應時間越長,權重越小,被選中的可能性越低
ZoneAvoidanceRule 復合判斷Server所在Zone的性能和Server的可用性選擇Server,在沒有Zone的環境下,類似於輪詢(RoundRobinRule)

Ribbon 的自定義配置

實現目的:通過自定義配置實現隨機選擇


Java 代碼配置方式

  • UserCenterRibbonConfiguration.java
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Configuration;
import ribbonconfiguration.RibbonConfiguration;

/**
 * @Description 用戶中心配置類
 */
@Configuration
@RibbonClient(name = "user-center", configuration = RibbonConfiguration.class)
public class UserCenterRibbonConfiguration {
}
  • RibbonConfiguration.java
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description Ribbon的配置類
 *      Ribbon的配置類要有@Configuration注解,但不能被@ComponentScan重復掃描
 *      否則就會被所有的RibbonClient共享
 */
@Configuration
public class RibbonConfiguration {

	/**
     * 自定義負載均衡規則
     * RandomRule 隨機選擇
     * @return
     */
    @Bean
    public IRule ribbonRule() {
        return new RandomRule();
    }
}
  • 目錄結構如下所示,Ribbon配置類RibbonConfiguration.java位置在java目錄下,其作用是避免父子上下文重疊,Ribbon的配置類要有@Configuration注解,但不能被@ComponentScan重復掃描,否則就會被所有的RibbonClient共享

在這里插入圖片描述

  • 接口訪問測試發現隨機訪問已實現

在這里插入圖片描述
在這里插入圖片描述


yml 屬性配置方式

  • 注釋Java代碼配置方式中的代碼,在application.yml中添加user-center的負載均衡規則,也能實現相同的效果
user-center:
  ribbon:
    # Ribbon負載均衡規則的全路徑
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

Ribbon 的全局配置

  • 有自定義配置就有全局配置,可以通過修改@RibbonClient注解為@RibbonClients注解實現全局配置
  • UserCenterRibbonConfiguration.java
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Configuration;
import ribbonconfiguration.RibbonConfiguration;

/**
 * @Description 用戶中心配置類
 */
@Configuration
@RibbonClients(defaultConfiguration = RibbonConfiguration.class)
public class UserCenterRibbonConfiguration {
}
  • RibbonConfiguration.java
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description Ribbon的配置類
 */
@Configuration
public class RibbonConfiguration {

	/**
     * 自定義負載均衡規則
     * RandomRule 隨機選擇
     * @return
     */
    @Bean
    public IRule ribbonRule() {
        return new RandomRule();
    }
}

Ribbon 的飢餓加載

  • 默認情況下Ribbon是懶加載的,當RestTemplate第一次調用RibbonClient時才會創建一個client,這樣會導致首次請求過慢或失敗的問題,可以通過屬性配置開啟Ribbon的飢餓加載

  • application.yml

ribbon:
  eager-load:
    # 開啟飢餓加載
    enabled: true
    # 為哪些RibbonClient開啟飢餓加載,多個用 "," 隔開
    clients: user-center

項目源碼



- End -
白嫖有風險
點贊加收藏


免責聲明!

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



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