1. 程式人生 > >Spring Cloud-04使用Ribbon實現客戶端負載均衡

Spring Cloud-04使用Ribbon實現客戶端負載均衡

文章目錄

概述

Spring Cloud-03將微服務註冊到Eureka Server上 + 為Eureka Server新增使用者認證中遺留的問題還記得吧 ,對,服務消費者呼叫服務提供者是硬編碼的方式,雖然把地址配置到了application.yml中,但是一旦服務端的地址發生改變,那肯定是要修改配置檔案的。

如何解決呢? Spring Cloud整合了Ribbon.

Ribbon是Nextflix釋出的負載均衡器,為Ribbon配置服務提供者地址後,Ribbon就可以基於某種負載均衡的演算法,自動幫助服務消費者請求。

Ribbon支援輪詢、隨機等負載均衡演算法,當然也支援實現自定義的負載均衡演算法。

在Spring Cloud中,當Ribbon和Eureka配合使用時,Ribbon可自動從Eureka Server獲取服務提供者的地址列表,並基於某種負載均衡演算法,請求其中一個服務提供者例項。

在這裡插入圖片描述


Ribbon演示

服務提供者微服務改造為使用MySql資料庫

當然了,這一步不是必須的。

Step1 修改pom.xml增加mysql的依賴

<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
</dependency>

Step2: applicaiton.yml中關於資料庫的部分調整為

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/artisan?useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root password: root driver-class-name: com.mysql.jdbc.Driver

新建服務消費者微服務,配置Ribbon

Step1: 為了方便,我們複製下micorservice-consumer-movie,修改為micorservice-consumer-movie-ribbon
在這裡插入圖片描述


Step2: pom.xml引入ribbon依賴

<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

Step3: 為RestTemplate新增@LoadBalanced註解

在這裡插入圖片描述

只需要為RestTemplate新增@LoadBalanced註解,就可以為RestTemlate整合Ribbon,使其具備負載均衡的能力


Step4: 修改Controller層程式碼,將地址調整為註冊在Eureka上的虛擬主機名

package com.artisan.microservice.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.artisan.microservice.model.User;

import lombok.extern.slf4j.Slf4j;


@RestController
@Slf4j
public class MovieController {
 
  @Autowired
  private RestTemplate restTemplate;

  
  @Autowired
  LoadBalancerClient loadBalancerClient;
  
  @GetMapping("/movie/{id}")
  public User findById(@PathVariable Long id) {
	 // 呼叫註冊在Eureka上的服務端的地址
    return this.restTemplate.getForObject("http://microservice-provider-user/user/" + id, User.class);
  }
  
  @GetMapping("/callProvider")
  public String callUserInstance() {
	  ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
	  // 列印當前選擇的哪個節點
	  log.info("serviceId: {} , host: {} ,port: {} ,uri: {}" ,serviceInstance.getServiceId() , serviceInstance.getHost(), serviceInstance.getPort(),serviceInstance.getUri());
	  return serviceInstance.getUri().toString();
  }  
}

我們把地址修改為了http://microservice-provider-user/user , 其中
microservice-provider-user使用者微服務的虛擬主機名,是註冊在Eureka Server上的名字,也是服務提供者微服務的配置檔案中配置的spring.application.name在這裡插入圖片描述
當Ribbon和Eureka同時使用時,會自動將虛擬主機名對映為微服務的網路地址。

同時為了更加直觀的獲取當前選擇的使用者微服務節點,我們新增加了個方法callProvider,待會測試就可以看到效果了。


Step5: 驗證Ribbon提供的能力

1.啟動Eureka Server
2.啟動兩個 microservice-provider-user例項 。(在STS中啟動一個後,修改下application.yml的埠,再次run as spring boot app 即可啟動第二個例項,以此類推)
3.啟動microservice-provider-movie-ribbon
4.訪問Eureka Server的頁面,檢視是否註冊成功

http://localhost:8761/login

在這裡插入圖片描述

登入後,可以看到2個服務提供者,1個服務消費者都成功的註冊到了Eureka Server上。
在這裡插入圖片描述

我們在服務消費者微服務,呼叫的地址為
在這裡插入圖片描述,對應兩個服務提供者的地址。

同時我們在服務消費者微服務工程中,為RestTemplate標註了@LoadBalanced註解,所以會使用Ribbon的負載均衡演算法來分發到不同的服務提供者地址

多次訪問 http://localhost:7902/movie/1 ,觀察控制檯每個節點的日誌輸出情況。

同時訪問http://localhost:7902/callProvider

在這裡插入圖片描述
在這裡插入圖片描述


注意事項

  1. 預設情況下,虛擬主機名和服務名稱是一致的,也可以通過eureka.instance.virtual-host-name或者eureka.instance.secure-virtual-host-name指定虛擬主機名

  2. 不能將restTemplate.getForObject()和loadBalancerClient寫在同一個方法中,兩者會衝突,因為RestTemplate實際上是一個Ribbon客戶端,本身已經包含了choose的行為

  3. 虛擬主機名不能包含"_"之類的字元,否則Ribbon再呼叫的時候會丟擲異常


原始碼

https://github.com/yangshangwei/SpringCloudMaster