Spring Cloud 入門教程(五): Ribbon實現客戶端的負載均衡

接上節,假如我們的Hello world服務的訪問量劇增,用一個服務已經無法承載, 我們可以把Hello World服務做成一個集羣。

很簡單,我們只需要複製Hello world服務,同時將原來的端口8762修改爲8763。然後啓動這兩個Spring Boot應用, 就可以得到兩個Hello World服務。這兩個Hello world都註冊到了eureka服務中心。這時候再訪問http://localhost:8761, 可以看到兩個hello world服務已經註冊。(服務與註冊參見Spring Cloud 入門教程(一): 服務註冊)。
在這裏插入圖片描述
1. 客戶端的負載均衡

負載均衡可分爲服務端負載均衡和客戶端負載均衡,服務端負載均衡完全由服務器處理,客戶端不需要做任何事情。而客戶端負載均衡技術,客戶端需要維護一組服務器引用,每次客戶端向服務端發請求的時候,會根據算法主動選中一個服務節點。常用的負載均衡算法有: Round Robbin, Random,Hash,StaticWeighted等。

Spring 提供兩輛種服務調度方式:Ribbon+restful和Feign。Ribbon就是一個基於客戶端的負載均衡器, Ribbon提供了很多在HTTP和TCP客戶端之上的控制.

Feign內部也已經使用了Ribbon, 所以只要使用了@FeignClient註解,那麼這一章的內容也都是適用的。

下面就看看如何Spring Cloud如何用Ribbon來實現兩個Hello World服務的負載均衡。以下是Spring cloud的ribbon客戶端負載均衡架構圖。
在這裏插入圖片描述
hello world服務和ribbon均註冊到服務中心

service-hi工程跑了兩個副本,端口分別爲8762,8763,分別向服務註冊中心註冊, 當sercvice-ribbon通過restTemplate調用service-Hellowworld的接口時,利用用ribbon進行負載均衡,會輪流的調用處於兩個不同端口的Hello world服務
2. 創建一個Ribbon服務

1) 創建一個maven工程,取名叫service-ribbon, pom.xml文件如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.chry</groupId>
    <artifactId>springcloud.helloworld.ribbon.service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>springcloud.helloworld.ribbon.service</name>
    <description>Demo project for Spring Cloud Ribbon</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <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>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Dalston.RC1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

2). 創建主類ServiceRibbonApplication

package springcloud.helloworld.ribbon.service;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class ServiceRibbonApplication {

public static void main(String[] args) {
    SpringApplication.run(ServiceRibbonApplication.class, args);
}

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

@EnableDiscoveryClient向服務中心註冊,並且註冊了一個叫restTemplate的bean。
@ LoadBalanced註冊表明,這個restRemplate是需要做負載均衡的。

3). 創建獲取一個獲取Hello內容的service類

 1 package springcloud.helloworld.ribbon.client;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.stereotype.Service;
 5 import org.springframework.web.client.RestTemplate;
 6 
 7 @Service
 8 public class HelloService {
 9     @Autowired RestTemplate restTemplate;
10 
11     public String getHelloContent() {
12         return restTemplate.getForObject("http://SERVICE-HELLOWORLD/",String.class);
13     }
14 }

這裏關鍵代碼就是, restTemplate.getForObject方法會通過ribbon負載均衡機制, 自動選擇一個Hello word服務,

這裏的URL是“http://SERVICE-HELLOWORLD/",其中的SERVICE-HELLOWORLD是Hello world服務的名字,而註冊到服務中心的有兩個SERVICE-HELLOWORLD。 所以,這個調用本質是ribbon-service作爲客戶端根據負載均衡算法自主選擇了一個作爲服務端的SERVICE-HELLOWORLD服務。然後再訪問選中的SERVICE-HELLOWORLD來執行真正的Hello world調用。
3. 啓動ribbon-service應用,我們就可以訪問http://localhost:8901/, 然後每次刷新可以看到以下兩種結果交替出現,表明實際調用的是在不同端口的不同的SERVICE-HELLOWORLD。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章