springcloud微服務五:客戶端負載均衡ribbon

一、基本概念理解

ribbon用在客戶端,或者說消費端,被稱作客戶端負載均衡。
對於這個稱呼,可以解析爲三個部分,一個是客戶端,一個是負載均衡,然後就是客戶端負載均衡。
根據個人理解,所有發起請求的一端、去拿東西的一端,都可以稱之爲客戶端或消費端。
而負載均衡,一般則是針對於至少兩個以上的集羣而言,重點在於均衡。從相對論的角度而言,一切都是相對的,那麼也就不存在絕對的均衡,因此所謂的均衡就需要一定的標準,如何達到這個標準,則需要一定的控制,即負載均衡策略,也可以稱之爲規則。
對於客戶端負載均衡,則可以很好的理解爲,這是相對於服務端負載均衡而言。相對於服務端負載均衡而言,客戶端負載均衡的好處就在於各個客戶端自己實現負載均衡運算,從而降低了服務端的壓力。壞處在於客戶端要自己實現負載,就需要清楚服務端集羣的狀態,增加了客戶端的複雜度以及多個客戶端下可能看起來的功能冗餘。

二、基本用法

1、pom.xml配置

ribbon的基本用法,實際上之前提過,首先還是一樣需要創建一個springboot項目,然後配置maven的pom.xml文件

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    <relativePath/> 
</parent>
......
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
......
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Edgware.SR2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

注:由於和之前四篇隔得時間較長,且目前工作實際項目使用的版本是springboot1.5.0和springcloud-Edgware.SR2,因此這之後的代碼示例也均已這兩個版本爲主。

2、properties文件配置

服務名
spring.application.name=ribbon-client
服務端口
server.port=9098
是否允許ip訪問
eureka.instance.prefer-ip-address=true
指定註冊中心的地址
eureka.client.serviceUrl.defaultZone=http://localhost:10010/eureka/

2、基本代碼
配置好pom.xml和properties文件後之後,在springcloud啓動類類名上方加入springboot的啓動註解以及springcloud客戶端註解

@EnableDiscoveryClient
@SpringBootApplication

之後,在啓動類中加入 RestTemplate的初始化代碼,並使用@Bean註解告知springboot管理,同時加入@LoadBalanced註解,代表使用ribbon負載均衡來管理RestTemplate,這一段代碼大致如下:

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

有了上邊的代碼,我們在其他被spring管理的組件中就可以使用@Autowired這樣的方式注入RestTemplate,一個被ribbon管理的RestTemplate,如下邊所示:

@service
public interface RibbonService {
    @Autowired
    RestTemplate restTemplate;

    public String sayHello() {
        ResponseEntity responseEntity = restTemplate.getForEntity("http://client/hello", String.class);
        return responseEntity.getBody();
    }}
  

三、內置負載均衡策略

RoundRobinRule線性輪詢策略
上邊的簡單實現,只使用了@LoadBalanced註解來開啓ribbon負載均衡,那麼就會使用ribbon默認的負載均衡策略,即線性輪詢。
就如我們用酷狗等音樂播放器放歌一樣,有很多方式,例如單曲循環、列表循環、隨機播放,這裏的線性輪詢其實就是列表循環,放歌循環的是歌曲列表,線性輪詢循環的是服務器列表,針對一系列的請求,從前到後依次訪問列表中的服務器,到了最後邊,就再回到開頭。
雖然在多個服務端的情況下,線性輪詢已經可以一定程度的實現負載均衡,大概也是實際使用率最高的一種方式,但是也有它的侷限性,因此ribbon還內置了其他一些負載均衡策略供我們選擇。

我們目前項目中就只使用了默認的負載均衡策略,不過也對其他策略有過一定的瞭解,下邊幾個是我個人認爲可能也會用到的:
RandomRule隨機選擇策略
隨機二字應該就不需要多做解釋了;
RetryRule線性輪詢重試策略
這個策略內部實際上還是用的線性輪詢,與默認的線性輪詢不一樣的地方在於,這個策略在訪問輪詢到的服務有問題時,會在一定的時間內進行重試,這個時間可以通過maxRetryMillis參數進行配置。
WeightedResponseTimeRule權重響應時間策略
這個策略是對線性輪詢的拓展,在線性輪詢的情況下,不論服務器實例的性能如何,在一定的請求次數下都必然會被輪詢到,這樣一來,如果某個實例由於某些原因,響應時間遠大於其他實例,就必然影響整體性能。
而WeightedResponseTimeRule則會對每個服務實例的響應時間進行一定的記錄和計算,然後給每個實例一個權重值區間。
如果上邊的權重值最大值小於0.001,那麼之後的請求會採用線性輪詢策略;如果大於0.001,那麼對於每一個請求,會隨機分配一個0到最大權重值之間的隨機數,然後這個隨機數在實力列表中哪個實例的權重區間內,就會選擇哪個實例。
那麼這裏有一個細節,就是隨機數算法中含頭不含尾,也就是說在0到最大權重值之間的隨機數,可以是0,卻不會是最大權重值那個值。
另一個細節就是,根據這裏的權重算法,平均響應時間越短的服務實例,它的權重區間就會越大,注意,是權重區間越大,而不是權重值。再明確點說,就是這個實力區間內能容納的隨機數個數更多。
因此,在生成隨機數的時候,這個區間命中的概率就越大,這個實例被選擇到的機率也更高,從而就使得平均響應時間短的實例更容易被選擇到,就提升了系統效率。

除了上邊四種,還有諸如最好可用策略BestAvailableRule等策略,就不再記錄。
同時,還可以自己定義負載均衡策略,但是應該很少會被用到,因爲內置的這些已經能夠滿足非常多的應用場景了。

那麼,瞭解了不同的負載均衡策略之後,還需要知道的當然就是如何使用非默認的負載均衡策略了。
其實也比較簡單,只需要在加一個讓spring來管理的bean就好,如下邊這樣:

@Bean
public IRule ribbonRule() {
        // return new RandomRule();
        // return new RetryRule();
        return new WeightedResponseTimeRule();
 }
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章