天天看點

SpringCloud Ribbon組成和負載均衡規則

Ribbon饑餓加載

預設情況下Ribbon是懶加載的。當服務起動好之後,第一次請求是非常慢的,第二次之後就快很多。

解決方式:開啟饑餓加載

ribbon:
 eager-load:
  enabled: true #開啟饑餓加載
  clients: server-1,server-2,server-3 #為哪些服務的名稱開啟饑餓加載,多個用逗号分隔           

Ribbon組成

接口 作用 預設值

IclientConfig

讀取配置

DefaultClientConfigImpl

IRule

負載均衡規則,選擇執行個體

ZoneAvoidanceRule

IPing

篩選掉ping不通的執行個體

DumyPing

(該類什麼不幹,認為每個執行個體都可用,都能ping通)

ServerList<Server>

交給Ribbon的執行個體清單 Ribbon:

ConfigurationBasedServerList

Spring Cloud Alibaba:

NacosServerList

ServerListFilter<Server>

過濾掉不符合條件的執行個體

ZonePreferenceServerListFilter

ILoadBalancer

Ribbon的入口

ZoneAwareLoadBalancer

ServerListUpdater

更新交給Ribbon的List的政策

PollingServerListUpdater

這裡的每一項都可以自定義

IclientConfig

Ribbon支援非常靈活的配置就是由該元件提供的

IRule

為Ribbon提供規則,進而選擇執行個體、該元件是最核心的元件

舉例:

代碼方式

@Configuration
public class RibbonRuleConfig {
    @Bean
    public IRule ribbonRulr() {
        return new RandomRule();
    }
    @Bean
    public IPing iPing(){
        return new PingUrl();
    }
}           

配置屬性方式

<clientName>:
 ribbon:
  NFLoadBalancerClassName: #ILoadBalancer該接口實作類
  NFLoadBalancerRuleClassName: #IRule該接口實作類
  NFLoadBalancerPingClassName: #Iping該接口實作類
  NIWSServerListClassName: #ServerList該接口實作類
  NIWSServerListFilterClassName: #ServiceListFilter該接口實作類           

在這些屬性中定義的類優先于使用

@RibbonClient(configuration=RibbonConfig.class)

Spring 定義的bean 以及由Spring Cloud Netflix提供的預設值。描述:配置檔案中定義ribbon優先代碼定義

Ribbon負載均衡的八種算法,其中

ResponseTimeWeightedRule

已廢除

規則名稱 特點

AvailabilityFilteringRule

過濾掉一直連接配接失敗的被标記為circuit tripped(電路跳閘)的後端Service,并過濾掉那些高并發的後端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

實作負載均衡<細粒度>配置-随機

方式一:JAVA代碼方式

首先定義RestTemplate,并且添加注解

@LoadBalanced

,這樣RestTemplate就實作了負載均衡

@LoadBalanced
@Bean
public RestTemplate restTemplate() {
//template.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));//解決中文亂碼
return new RestTemplate();
}           

在SpringBootApplication主類下添加配置類。該類主要作用于為哪個服務做負載均衡。預設的是輪訓

@Configuration
@RibbonClient(name = "${服務名稱}", configuration = GoodsRibbonRuleConfig.class)//configuration: 指向負載均衡規則的配置類
public class GoodsRibbonConfig {
}           

添加Ribbon的配置類,注意該類必須配置在

@SpringBootApplication

主類以外的包下。不然的話所有的服務都會按照這個規則來實作。會被所有的RibbonClient共享。主要是主類的主上下文和Ribbon的子上下文起沖突了。父子上下文不能重疊。相關連接配接:

https://blog.csdn.net/qq_32588349/article/details/52097943
@Configuration
public class GoodsRibbonRuleConfig {
    @Bean
    public IRule ribbonRulr() {
        return new RandomRule();
    }
}           

或者使用自定義注解排除該類

方式一:配置屬性方式

server-1: # 服務名稱 Service-ID
  ribbon:
    # 屬性配置方式【推薦】
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #  配置檔案配置負載均衡算法-我這裡使用的是自定義的Ribbon的負載均衡算法,預設           

優先級:配置(不會影響其他服務)>(大于) 寫死(類得寫在SpringBoot啟動類包外,不然會影響其他服務)

總結:

配置方式 有點 缺點
代碼配置 基于代碼,更加靈活

有坑(父子上下文)

線上修改得重新打包,釋出

屬性配置

易上手 配置更加直覺

線上修改無需重新打包,釋出

優先級更高

極端場景下沒有配置配置方式靈活

實作負載均衡<全局>配置-随機

方式一:Ribbon的配置類定義在主類下

讓ComponentScan上下文重疊(強烈不建議使用)

方式二:

@Configuration
@RibbonClients(defaultConfiguration = GoodsRibbonRuleConfig.class)//Ribbon負載均衡全局粒度配置(所有服務都按照這個配置)
public class RibbonConfig {
}