Spring Cloud:使用Ribbon實現負載均衡詳解(下)

在上一篇文章(Spring Cloud:使用Ribbon實現負載均衡詳解(上))中,我對 Ribbon 作了一個介紹,Ribbon 能夠實現直接經過服務名稱對服務進行訪問。這一篇文章我詳細分析一下如何使用 Ribbon 實現客戶端的負載均衡。算法

1. 使用 Ribbon 實現負載均衡

要實現負載均衡,首先要有多個訂單服務提供者,目前咱們就一個 microservice-order-provider01,端口號 8001,咱們能夠仿照這個服務,再建立兩個子模塊,也是訂單服務提供者,取名爲 microservice-order-provider02,端口號 8002 和 microservice-order-provider03,端口號 8003。spring

如今三個訂單服務有了,再加上 Ribbon 和 Eureka 集羣后,系統的架構以下:數據庫

Ribbon 是客戶端的負載均衡工具,它在服務的消費方,首先三個訂單服務 800一、8002 和 8003 都會註冊到 Eureka 集羣,Ribbon 會先從 Eureka 集羣(700一、7002 和 7003)中查詢可用的服務列表,而後根據 Ribbon 提供的負載均衡算法,負載均衡的請求可用的訂單服務。瀏覽器

Ribbon 默認的負載均衡算法是輪詢,也就是按順序挨個的調用。咱們先來搭建一下整個服務架構,上面提到了,首先要拷貝兩個訂單服務,端口號分別爲 8002 和 8003,一塊兒來對比看下三個訂單服務的配置文件。bash

8001 端口的訂單服務配置:服務器

# 服務端口號
server:
 port: 8001

# 數據庫地址
datasource:
 url: localhost:3306/microservice01
# 省略數據庫的基本配置

spring:
 application:
   name: microservice-order # 對外暴露的服務名稱

# 客戶端註冊進eureka服務列表裏
eureka:
 client:
   service-url:
     defaultZone: http://eureka01:7001/eureka/,http://eureka02:7002/eureka/,http://eureka03:7003/eureka/,
 instance:
   instance-id: 書籍訂單服務-8001  # 人性化顯示出服務的信息
   prefer-ip-address: true    # 訪問路徑可顯示ip地址
複製代碼

8002 端口的訂單服務配置:架構

# 服務端口號
server:
 port: 8002

# 數據庫地址
datasource:
 url: localhost:3306/microservice02
# 數據庫基本配置省略

spring:
 application:
   name: microservice-order # 對外暴露的服務名稱

# 客戶端註冊進eureka服務列表裏
eureka:
 client:
   service-url:
     defaultZone: http://eureka01:7001/eureka/,http://eureka02:7002/eureka/,http://eureka03:7003/eureka/,
 instance:
   instance-id: 書籍訂單服務-8002  # 人性化顯示出服務的信息
   prefer-ip-address: true    # 訪問路徑可顯示ip地址
複製代碼

8003 端口的訂單服務配置:併發

# 服務端口號
server:
 port: 8003

# 數據庫地址
datasource:
 url: localhost:3306/microservice03
# 數據庫基本配置省略

spring:
 application:
   name: microservice-order # 對外暴露的服務名稱


# 客戶端註冊進eureka服務列表裏
eureka:
 client:
   service-url:
     defaultZone: http://eureka01:7001/eureka/,http://eureka02:7002/eureka/,http://eureka03:7003/eureka/,
 instance:
   instance-id: 書籍訂單服務-8003  # 人性化顯示出服務的信息
   prefer-ip-address: true    # 訪問路徑可顯示ip地址
複製代碼

對比後發現,有幾個地方須要注意:app

  • 對外暴露的服務名稱必需要相同,由於都是同一個服務,只不過有多個而已,由於接下來Ribbon是經過服務名來調用服務的;
  • 每一個服務鏈接了不一樣的數據庫,這樣用來區分不一樣的服務,便於測試,實際中也多是便於維護;
  • 每一個服務的個性化名稱展現能夠區分一下,這樣在eureka裏能夠很好的辨別出來

Eureka 集羣仍是使用前面的 700一、7002 和 7003,首先咱們啓動 Eureka 集羣,而後分別啓動 800一、8002 和 8003 三個訂單服務。(友情提示:這裏已經啓動了6個工程了,若是電腦的性能跟不上的話,可能已經開始卡頓了)。負載均衡

啓動了以後,能夠訪問下 eureka01:7001,看下三個訂單服務是否正常註冊到 eureka 集羣裏。以下圖,說明集羣和訂單服務均正常。

OK,接下來就是重點了,咱們啓動服務消費方,也就是上一節中的訂單消費服務,而後在瀏覽器輸入 http://localhost:9001/consumer/order/get/1 便可查詢到對應的訂單服務:

{"id":1,"name":"跟着社會一塊兒學 Spring Boot","price":39.99,"dbSource":"microservice03"}
複製代碼

刷新頁面,能夠看到,結果以下:

{"id":1,"name":"跟着社會一塊兒學 Spring Boot","price":39.99,"dbSource":"microservice01"}
複製代碼

再刷新頁面,能夠看到,結果以下:

{"id":1,"name":"跟着社會一塊兒學 Spring Boot","price":39.99,"dbSource":"microservice02"}
複製代碼

能夠看到,dbsource的值一在 microservice0一、microservice02 和 microservice03 之間輪詢切換(這個值是我在三個數據庫中設置的不一樣的值,就是爲了在這展現,方便看到效果),這就說明了,Ribbon 的負載均衡已經起做用了,客戶端會輪詢的根據服務名,從 800一、8002 和 8003 之間切換訪問,從而達到負載均衡的效果。

同時,也能夠看到,Ribbon 的默認負載均衡算法是輪詢。

2. 如何指定 Ribbon 的負載均衡策略

由上面的結果可知,Ribbon 默認的策略是輪詢,那麼 Ribbon 除了輪詢,還有哪些負載均衡的策略呢?咱們如何去設置本身想要的策略呢?

Ribbon 自帶的負載均衡策略有以下幾個:

  • RoundRibbonRule:輪詢。人人有份,一個個來!
  • RandomRule:隨機。拼人品了!
  • AvailabilityFilteringRule:先過濾掉因爲屢次訪問故障而處於斷路器跳閘狀態的服務,以及併發鏈接數超過閾值的服務,剩下的服務,使用輪詢策略。
  • WeightedResponseTimeRule:根據平均響應時間計算全部服務的權重,響應越快的服務權重越高,越容易被選中。一開始啓動時,統計信息不足的狀況下,使用輪詢。
  • RetryRule:先輪詢,若是獲取失敗則在指定時間內重試,從新輪詢可用的服務。
  • BestAvailableRule:先過濾掉因爲屢次訪問故障而處於斷路器跳閘狀態的服務,而後選擇一個併發量最小的服務。
  • ZoneAvoidanceRule:複合判斷 server 所在區域的性能和 server 的可用性選擇服務器

如何指定 Ribbon 自帶的負載均衡策略呢?咱們須要在配置類中指定一下便可,以下:

/**
* 配置RestTemplate
* @author shengwu ni
*/
@Configuration
public class RestTemplateConfig {

   /**
    * '@LoadBalanced'註解表示使用Ribbon實現客戶端負載均衡
    * @return RestTemplate
    */
   @Bean
   @LoadBalanced
   public RestTemplate getRestTemplate() {
       return new RestTemplate();
   }

   /**
    * 指定其餘負載均衡策略
    * @return IRule
    */
   @Bean
   public IRule myRule() {
       // 指定重試策略:先輪詢,若獲取失敗則在指定時間內重試,從新輪詢可用的服務。
       return new RetryRule();
   }
}
複製代碼

咱們能夠 new 出以上對應的策略,來實現對應的負載均衡,讀者能夠 new RandomRule() 測試一下隨機策略,而後重複刷新上面的測試地址,能夠發現是隨機請求三個服務。其餘的策略,讀者能夠自行嘗試一下。

相關文章
相關標籤/搜索