一、基本概念理解
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(); }