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文件如下:

 

 1 <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">
 2     <modelVersion>4.0.0</modelVersion>
 3     <groupId>com.chry</groupId>
 4     <artifactId>springcloud.helloworld.ribbon.service</artifactId>
 5     <version>0.0.1-SNAPSHOT</version>
 6     <packaging>jar</packaging>
 7     <name>springcloud.helloworld.ribbon.service</name>
 8     <description>Demo project for Spring Cloud Ribbon</description>
 9 
10     <parent>
11         <groupId>org.springframework.boot</groupId>
12         <artifactId>spring-boot-starter-parent</artifactId>
13         <version>1.5.3.RELEASE</version>
14         <relativePath/> <!-- lookup parent from repository -->
15     </parent>
16 
17     <properties>
18         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
19         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
20         <java.version>1.8</java.version>
21     </properties>
22 
23     <dependencies>
24         <dependency>
25             <groupId>org.springframework.cloud</groupId>
26             <artifactId>spring-cloud-starter-eureka</artifactId>
27         </dependency>
28         <dependency>
29             <groupId>org.springframework.cloud</groupId>
30             <artifactId>spring-cloud-starter-ribbon</artifactId>
31         </dependency>
32         <dependency>
33             <groupId>org.springframework.boot</groupId>
34             <artifactId>spring-boot-starter-web</artifactId>
35         </dependency>
36 
37         <dependency>
38             <groupId>org.springframework.boot</groupId>
39             <artifactId>spring-boot-starter-test</artifactId>
40             <scope>test</scope>
41         </dependency>
42     </dependencies>
43 
44     <dependencyManagement>
45         <dependencies>
46             <dependency>
47                 <groupId>org.springframework.cloud</groupId>
48                 <artifactId>spring-cloud-dependencies</artifactId>
49                 <version>Dalston.RC1</version>
50                 <type>pom</type>
51                 <scope>import</scope>
52             </dependency>
53         </dependencies>
54     </dependencyManagement>
55 
56     <build>
57         <plugins>
58             <plugin>
59                 <groupId>org.springframework.boot</groupId>
60                 <artifactId>spring-boot-maven-plugin</artifactId>
61             </plugin>
62         </plugins>
63     </build>
64 
65     <repositories>
66         <repository>
67             <id>spring-milestones</id>
68             <name>Spring Milestones</name>
69             <url>https://repo.spring.io/milestone</url>
70             <snapshots>
71                 <enabled>false</enabled>
72             </snapshots>
73         </repository>
74     </repositories>
75 </project>

 

2). 創建主類ServiceRibbonApplication

 1 package springcloud.helloworld.ribbon.service;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 6 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
 7 import org.springframework.context.annotation.Bean;
 8 import org.springframework.web.client.RestTemplate;
 9 
10 @SpringBootApplication
11 @EnableDiscoveryClient
12 public class ServiceRibbonApplication {
13 
14     public static void main(String[] args) {
15         SpringApplication.run(ServiceRibbonApplication.class, args);
16     }
17 
18     @Bean
19     @LoadBalanced
20     RestTemplate restTemplate() {
21         return new RestTemplate();
22     }
23 }

@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。

            

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