欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringCloud?LoadBalancerClient?負載均衡原理解析

 更新時間:2022年02月14日 10:28:19   作者:張維鵬  
LoadBalancerClient?是?SpringCloud?提供的一種負載均衡客戶端,Ribbon?負載均衡組件內(nèi)部也是集成了?LoadBalancerClient?來實現(xiàn)負載均衡,本文給大家深入解析?LoadBalancerClient?接口源碼,感興趣的朋友跟隨小編一起看看吧

        LoadBalancerClient 是 SpringCloud 提供的一種負載均衡客戶端,Ribbon 負載均衡組件內(nèi)部也是集成了 LoadBalancerClient 來實現(xiàn)負載均衡。那么 LoadBalancerClient 內(nèi)部到底是如何做到的呢?我們先大概講一下 LoadBalancerClient 的實現(xiàn)原理,然后再深入源碼中進行解析。

        LoadBalancerClient 在初始化時會通過 Eureka Client 向 Eureka 服務端獲取所有服務實例的注冊信息并緩存在本地,并且每10秒向 EurekaClient 發(fā)送 “ping”,來判斷服務的可用性。如果服務的可用性發(fā)生了改變或者服務數(shù)量和之前的不一致,則更新或者重新拉取。最后,在得到服務注冊列表信息后,ILoadBalancer 根據(jù) IRule 的策略進行負載均衡(默認策略為輪詢)。

        當使用 LoadBalancerClient 進行遠程調(diào)用的負載均衡時,LoadBalancerClient 先通過目標服務名在本地服務注冊清單中獲取服務提供方的某一個實例,比如訂單服務需要訪問商品服務,商品服務有3個節(jié)點,LoadBalancerClient 會通過 choose() 方法獲取到3個節(jié)點中的一個服務,拿到服務的信息之后取出服務IP信息,就可以得到完整的想要訪問的IP地址和接口,最后通過 RestTempate 訪問商品服務。

深入解析 LoadBalancerClient 接口源碼:

1、LoadBalancerClient 源碼解析:

        LoadBalancerClient 是 Spring Cloud 提供的一個非常重要的接口,它繼承自 ServiceInstanceChooser 接口,該接口的實現(xiàn)類是 RibbonLoadBalanceClient,它們之間的關系如下圖所示:

(1)LoadBalancerClient 接口源碼:

首先我們開始追蹤 LoadBalancerClient 源碼:

public interface LoadBalancerClient extends ServiceInstanceChooser 
{
	<T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;
     
    <T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException;
    
    URI reconstructURI(ServiceInstance instance, URI original);
}

        可以發(fā)現(xiàn) LoadBalancerClient 接口繼承了 ServiceInstanceChooser 接口,主要的方法為2個 execute() 方法,均是用來執(zhí)行請求的。還有個 reconstructURI() 是用來重構(gòu)URL的。

(2)ServiceInstanceChooser 接口源碼:

繼續(xù)查看 LoadBalancerClient 繼承的 ServiceInstanceChooser 接口源碼,具體如下:

public interface ServiceInstanceChooser 
{
	ServiceInstance choose(String serviceId);
}

        ServiceInstanceChooser 接口中的主要方法為 choose(),該方法用于根據(jù)服務的名稱 serviceId 來選擇其中一個服務實例,即根據(jù) serviceId 獲取ServiceInstance。

(3)RibbonLoadBalanceClient 實現(xiàn)類源碼:

        接下來我們看看 LoadBalancerClient 的實現(xiàn)類 RibbonLoadBalanceClient,它用來執(zhí)行最終的負載均衡請求。其中,RibbonLoadBalanceClient 的一個 choose() 方法用于選擇具體的服務實例,其內(nèi)部是通過 getServer() 方法交給 ILoadBalancer 完成的。我們先看下 RibbonLoadBalanceClient 里面幾個重要實現(xiàn)方法的源碼:

① 第一個:choose(),用來選擇具體的服務實例。

@Override
	public ServiceInstance choose(String serviceId) {
		return choose(serviceId, null);
	}
	/**
	 * New: Select a server using a 'key'.
	 * @param serviceId of the service to choose an instance for
	 * @param hint to specify the service instance
	 * @return the selected {@link ServiceInstance}
	 */
	public ServiceInstance choose(String serviceId, Object hint) {
		Server server = getServer(getLoadBalancer(serviceId), hint);
		if (server == null) {
			return null;
		}
		return new RibbonServer(serviceId, server, isSecure(server, serviceId),
				serverIntrospector(serviceId).getMetadata(server));
	}

② 第二個:getServer(),獲取實例。

protected Server getServer(ILoadBalancer loadBalancer) {
		return getServer(loadBalancer, null);
	}
	protected Server getServer(ILoadBalancer loadBalancer, Object hint) {
		if (loadBalancer == null) {
			return null;
		}
        // 最終通過 loadBalancer 去做服務實例的選擇。
		// Use 'default' on a null hint, or just pass it on?
		return loadBalancer.chooseServer(hint != null ? hint : "default");
	}

        可以看到最終通過 loadBalancer 去做服務實例的選擇。那我們下面就看下 loadBalancer 是怎么怎么實現(xiàn)服務實例的選擇的?

(4)BaseLoadBalancer 源碼:

        我們從上面能看到 ILoadBalancer 中的 chooseServer 方法里面默認值為 default,進入ILoadBalancer 實現(xiàn)類 BaseLoadBalancer 的 chooseServer() 看下:

         我們的 key 的值為“default”,那么這個 key 代表的是什么意思呢?進去 rule 對象里面看下:

        可以看到這個 rule 是 IRule 接口聲明出來的,且默認定義的實現(xiàn)類是 RoundRobinRule(),也就是輪詢策略。那我們接下來看下 IRule 接口:

(5)IRule 接口源碼:

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();    
}

        我們可以看到 IRule 接口定義了3個方法,choose() 是用來選擇實例的,setLoadBalancer() 和 getLoadBalance() 用來設置和獲取 ILoadBalancer 的。那么接下來 IRule 接口有多少個實現(xiàn)類:

 (1)隨機策略 RandomRule:隨機數(shù)選擇服務列表中的服務節(jié)點Server,如果當前節(jié)點不可用,則進入下一輪隨機策略,直到選到可用服務節(jié)點為止

(2)輪詢策略 RoundRobinRule:按照接收的請求順序,逐一分配到不同的后端服務器

(3)重試策略 RetryRule:在選定的負載均衡策略機上重試機制,在一個配置時間段內(nèi)當選擇Server不成功,則一直嘗試使用 subRule 的方式選擇一個可用的server;

(4)可用過濾策略 PredicateBaseRule:過濾掉連接失敗 和 高并發(fā)連接 的服務節(jié)點,然后從健康的服務節(jié)點中以線性輪詢的方式選出一個節(jié)點返回

(5)響應時間權重策略 WeightedRespinseTimeRule:根據(jù)服務器的響應時間分配一個權重weight,響應時間越長,weight越小,被選中的可能性越低。主要通過后臺線程定期地從 status 里面讀取平均響應時間,為每個 server 計算一個 weight

(6)并發(fā)量最小可用策略 BestAvailableRule:選擇一個并發(fā)量最小的服務節(jié)點 server。ServerStats 的 activeRequestCount 屬性記錄了 server 的并發(fā)量,輪詢所有的server,選擇其中 activeRequestCount 最小的那個server,就是并發(fā)量最小的服務節(jié)點。該策略的優(yōu)點是可以充分考慮每臺服務節(jié)點的負載,把請求打到負載壓力最小的服務節(jié)點上。但是缺點是需要輪詢所有的服務節(jié)點,如果集群數(shù)量太大,那么就會比較耗時。

(7)區(qū)域權重策略 ZoneAvoidanceRule:綜合判斷 server 所在區(qū)域的性能 和 server 的可用性,使用 ZoneAvoidancePredicate 和 AvailabilityPredicate 來判斷是否選擇某個server,前一個判斷判定一個zone的運行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate 用于過濾掉連接數(shù)過多的Server。

同樣的,如果我們也可以通過實現(xiàn) IRule 接口來自定義一個負載均衡策略。

2、ILoadBalancer 源碼解析:

        ILoadBalancer 是一個接口,該接口定義了一系列實現(xiàn)負載均衡的方法,LoadBalancerClient 的實現(xiàn)類 RibbonLoadBalanceClient 也將負載均衡的具體實現(xiàn)交給了 ILoadBalancer 來處理,ILoadBalancer 通過配置 IRule、IPing 等,向 EurekaClient 獲取注冊列表信息,默認每10秒向 EurekaClient 發(fā)送一次 “ping”,進而檢查是否需要更新服務的注冊列表信息。最后,在得到服務注冊列表信息后,ILoadBalancer 根據(jù) IRule 的策略進行負載均衡。ILoadBalancer 接口的實現(xiàn)類結(jié)果如下圖所示:

        查看 BaseLoadBalancer 和 DynamicServerListLoadBalancer 源碼,默認情況下實現(xiàn)了以下配置:

(1)IClientConfig clientConfig:用于配置負載均衡客戶端,默認實現(xiàn)類是 DefaultClientConfigImpl。

(2)IRule rule:用于配置負載均衡的策略,默認使用的是 RoundRobinRule 輪詢策略。

(3)IPing ping:用于檢查當前服務是否有響應,從而判斷當前服務是否可用,默認實現(xiàn)類是 DummyPing,該實現(xiàn)類的 isAlive() 方法返回值是 true,默認所有服務實例都是可用的。

(4)ServerList serverList:用于獲取所有 Server 注冊列表信息。通過跟蹤源碼會發(fā)現(xiàn),ServerList 的實現(xiàn)類是 DiscoveryEnabledNIWSServerList,該類定義的 obtainServersViaDiscovery() 方法是根據(jù) eurekaClientProvider.get() 方法獲取 EurekaClient,再根據(jù) EurekaClient 獲取服務注冊列表信息。EurekaClient 的實現(xiàn)類是DiscoveryClient,DiscoveryClient 具有服務注冊、獲取服務注冊列表等功能。

(5)ServerListFilter filter:定義了根據(jù)配置過濾或者動態(tài)獲取符合條件的服務列表,默認實現(xiàn)類是 ZonePreferenceServerListFilter,該策略能夠優(yōu)先過濾出與請求調(diào)用方處于同區(qū)域的服務實例。

到此這篇關于SpringCloud LoadBalancerClient 負載均衡原理的文章就介紹到這了,更多相關SpringCloud LoadBalancerClient 負載均衡內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java?泛型考古?泛型擦除?包裝類詳細解析

    Java?泛型考古?泛型擦除?包裝類詳細解析

    泛型是在Java?SE?1.5引入的的新特性,本質(zhì)是參數(shù)化類型,也就是說所操作的數(shù)據(jù)類型被指定為一個參數(shù)。這種參數(shù)類型可以用在類、接口和方法的創(chuàng)建中,分別稱為泛型類、泛型接口、泛型方法,本篇我們一起來學習泛型考古、泛型擦除、包裝類
    2022-03-03
  • 一文詳解如何在控制臺顯示MyBatis的SQL語句

    一文詳解如何在控制臺顯示MyBatis的SQL語句

    這篇文章主要為大家介紹了如何在控制臺顯示MyBatis的SQL語句實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • Spring?@Autowired注解超詳細示例

    Spring?@Autowired注解超詳細示例

    @Autowired注解可以用在類屬性,構(gòu)造函數(shù),setter方法和函數(shù)參數(shù)上,該注解可以準確地控制bean在何處如何自動裝配的過程。在默認情況下,該注解是類型驅(qū)動的注入
    2022-08-08
  • java 打印一字符串,并在main()方法內(nèi)調(diào)用它

    java 打印一字符串,并在main()方法內(nèi)調(diào)用它

    編寫一個方法(名字自定,但要符合Java編碼規(guī)范),方法內(nèi)打印一字符串,并在main()方法內(nèi)調(diào)用它。
    2017-02-02
  • solr在java中的使用實例代碼

    solr在java中的使用實例代碼

    本篇文章主要介紹了solr在java中的使用實例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • Java 如何通過Magic 魔數(shù)獲取文件類型

    Java 如何通過Magic 魔數(shù)獲取文件類型

    魔數(shù)有很多種定義,這里我們討論的主要是在編程領域的定義,文件的起始幾個字節(jié)的內(nèi)容是固定的,本文給大家介紹Java Magic 魔數(shù)獲取文件類型的相關知識,感興趣的朋友一起看看吧
    2023-11-11
  • Java中Map的九種遍歷方式總結(jié)

    Java中Map的九種遍歷方式總結(jié)

    日常工作中?Map?絕對是我們?Java?程序員高頻使用的一種數(shù)據(jù)結(jié)構(gòu),那?Map?都有哪些遍歷方式呢?這篇文章就帶大家看一下,看看你經(jīng)常使用的是哪一種
    2022-11-11
  • Java?AQS中ReentrantLock條件鎖的使用

    Java?AQS中ReentrantLock條件鎖的使用

    ReentrantLock繼承了Lock接口,?lock方法實際上是調(diào)用了Sync的子類NonfairSync(非公平鎖)的lock方法。ReentrantLock的真正實現(xiàn)在他的兩個內(nèi)部類NonfairSync和FairSync中,默認實現(xiàn)是非公平鎖
    2023-02-02
  • Spring Security LDAP實現(xiàn)身份驗證的項目實踐

    Spring Security LDAP實現(xiàn)身份驗證的項目實踐

    在本文中,我們涵蓋了“使用 Spring Boot 的 Spring Security LDAP 身份驗證示例”的所有理論和示例部分,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-08-08
  • 你知道在Java中Integer和int的這些區(qū)別嗎?

    你知道在Java中Integer和int的這些區(qū)別嗎?

    最近面試,突然被問道,說一下Integer和int的區(qū)別.額…可能平時就知道寫一些業(yè)務代碼,包括面試的一些Spring源碼等,對于這種特別基礎的反而忽略了,導致面試的時候突然被問到反而不知道怎么回答了.哎,還是乖乖再看看底層基礎,順帶記錄一下把 ,需要的朋友可以參考下
    2021-06-06

最新評論