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

程式設計師私房菜發表於2019-01-16

前面幾篇文章主要介紹了 Spring Cloud 中的 Eureka 服務註冊與發現,這一篇文章主要介紹一下 Spring Cloud Ribbon,什麼是 Ribbon 呢?首先看一下 Ribbon 的相關介紹。

1. 什麼是 Ribbon?

Spring Cloud Ribbon 是一套實現客戶端負載均衡的工具。注意是客戶端,當然也有服務端的負載均衡工具,我們後面再介紹。可以認為 Ribbon 就是一個負載均衡器(Load Balancer,簡稱LB,即:low比~~)。負載均衡就是將使用者的請求平攤的分配到多個服務上,從而達到系統的高可用。

簡單來說,Ribbon 的主要功能是提供客戶端的軟體負載均衡演算法,將 Netflix 的中間層服務連線在一起。Ribbon 客戶端元件給我們提供了一套很完善的配置項,比如可以配置連線超時、重試等等。

再說的通俗一點,就是可以在配置檔案中列出 LB 後面所有的機器(即服務),Ribbon 會自動根據某種規則(如輪詢、隨機等等)去連線這些機器(即服務),我們也可以自定義一些負載均衡演算法。

再簡單點,Ribbon 就是一個類庫,整合在服務消費方,消費方從服務註冊中心獲知有哪些地址(即服務)可用,然後消費方透過 Ribbon 從這些地址當中選擇一個合適的伺服器來消費服務。

更多資料可以觀看官方GitHub:

2. Ribbon 的使用

我們在前面文章中,將訂單服務註冊到 Eureka,然後消費方可以透過 http 請求去獲取訂單的資訊,但是這是最原始的 http 呼叫,沒有任何 Ribbon 的東西在裡面,接下來我們要在消費方植入 Ribbon。

2.1 匯入 Ribbon 依賴

我們使用的Spring Cloud 版本是 Finchley,該版本需要匯入的依賴如下:

<!--eureka Client-->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--ribbon負載均衡依賴-->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

可以看到,Eureka Client 的依賴也需要匯入,因為服務註冊到了 Eureka,Ribbon 也需要和 Eureka 整合,所以在消費方也匯入了 Eureka 依賴。

2.2 配置 application.yml

server:
 port: 9001

eureka:
 client:
   register-with-eureka: false
   service-url:
     defaultZone: http://eureka01:7001/eureka/,

由前面的內容(Spring Cloud:使用Eureka叢集搭建高可用服務註冊中心)可知,我們搭建了一個 Eureka 叢集,那麼就用這個叢集,這個消費方我們設定不註冊到該叢集中。

2.3 向 http 中植入 Ribbon

這是什麼意思呢?之前的 消費方是使用 RestTemplate 來傳送 http 請求,呼叫訂單服務的,但是沒有負載均衡,所以現在我們要讓這個 http 呼叫自帶負載均衡。

即修改下 RestTemplate 配置:

/**
* 配置RestTemplate
* @author shengwu ni
*/

@Configuration
public class RestTemplateConfig {

   /**
    * '@LoadBalanced'註解表示使用Ribbon實現客戶端負載均衡
    * @return RestTemplate
    */

   @Bean
   @LoadBalanced
   public RestTemplate getRestTemplate() {
       return new RestTemplate();
   }
}

在方法上新增一個 @LoadBalanced 註解即可開啟 Ribbon 負載均衡。這樣就可以透過微服務的名字從 Eureka 中找到對應的服務並訪問了。

友情提示:別忘了在主啟動類上新增 @EnableEurekaClient,因為這個消費方也是一個 Eureka Client,剛剛我們已經匯入了 Eureka Client 的依賴了。

2.4 將ip改成服務名稱

剛剛提到了,開啟 Ribbon 負載均衡後,就可以透過微服務的名字從 Eureka 中找到對應的服務。我們先來看下原來是怎麼實現的。

/**
* 訂單消費服務
* @author shengwu ni
*/

@RestController
@RequestMapping("/consumer/order")
public class OrderConsumerController {

   /**
    * 訂單服務提供者模組的 url 字首
    */

//    private static final String ORDER_PROVIDER_URL_PREFIX = "
   private static final String ORDER_PROVIDER_URL_PREFIX = ";

   @Resource
   private RestTemplate restTemplate;

   @GetMapping("/get/{id}")
   public TOrder getOrder(@PathVariable Long id) {

       return restTemplate.getForObject(ORDER_PROVIDER_URL_PREFIX + "/provider/order/get/" + id, TOrder.class);
   }
}

可以看出,註釋掉的那部分,是原來的訪問方式,訂單提供服務是8001埠,現在我們將ip+埠號這種訪問方式,改成微服務名稱,這個名稱就是 Eureka 管理介面顯示的註冊進去的名稱,也即服務提供方的application.yml配置檔案中配置的服務名稱:

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

在前面文章中已經說了,不再贅述。

2.5 啟動服務,測試

還是和前面叢集文章中提到的一樣,分別啟動 eureka7001、eureka7002、eureka7003以及訂單服務8001,可以看到訂單服務已經註冊到 Eureka 叢集。

然後啟動消費方服務,然後在瀏覽器輸入 即可查詢到對應的訂單服務:

{"id":1,"name":"跟武哥一起學 Spring Boot","price":39.99,"dbSource":"microservice01"}

說明,我們透過訂單的服務名稱即可獲取訂單資訊了。可能到這裡,讀者還不明白我整了一大波,到最後就為了透過服務名稱去獲取服務提供的資訊嗎?

是的,這只是第一步,因為在很多微服務中,你不可能去透過每個 ip 和埠號來找對應的服務,更何況,還有 Ribbon 負載均衡還沒上場呢?同一個微服務名稱,可以有多個服務,而 Ribbon 只需要透過服務名去獲取服務資訊,至於獲取到的是哪一個?就看具體的負載均衡策略了,目前測試的 MICROSERVICE-ORDER 服務就一個提供者,所以不能體現出負載均衡。由於篇幅原因,下篇文章繼續。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31558358/viewspace-2563048/,如需轉載,請註明出處,否則將追究法律責任。

相關文章