業餘草 SpringCloud教程 | 第二篇: 服務消費者(rest+ribbon)(Finchley版本)

在上一篇文章,講了服務的註冊和發現。在微服務架構中,業務都會被拆分紅一個獨立的服務,服務與服務的通信是基於http restful的。Spring cloud有兩種服務調用方式,一種是ribbon+restTemplate,另外一種是feign。在這一篇文章首先講解下基於ribbon+rest。html

1、ribbon簡介

Ribbon is a client side load balancer which gives you a lot of control over the behaviour of HTTP and TCP clients. Feign already uses Ribbon, so if you are using @FeignClient then this section also applies.java

—–摘自官網git

ribbon是一個負載均衡客戶端,能夠很好的控制htt和tcp的一些行爲。Feign默認集成了ribbon。github

ribbon 已經默認實現了這些配置bean:web

  • IClientConfig ribbonClientConfig: DefaultClientConfigImplspring

  • IRule ribbonRule: ZoneAvoidanceRuleapache

  • IPing ribbonPing: NoOpPing瀏覽器

  • ServerList ribbonServerList: ConfigurationBasedServerList微信

  • ServerListFilter ribbonServerListFilter: ZonePreferenceServerListFilterrestful

  • ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer

2、準備工做

這一篇文章基於上一篇文章的工程,啓動eureka-server 工程;啓動service-hi工程,它的端口爲8762;將service-hi的配置文件的端口改成8763,並啓動,這時你會發現:service-hi在eureka-server註冊了2個實例,這就至關於一個小的集羣。

如何在idea下啓動多個實例,請參照這篇文章: 
https://blog.csdn.net/forezp/article/details/76408139

訪問localhost:8761如圖所示: 
如何一個工程啓動多個實例,請看這篇文章:https://blog.csdn.net/forezp/article/details/76408139

3、建一個服務消費者

從新新建一個spring-boot工程,取名爲:service-ribbon; 
在它的pom.xml繼承了父pom文件,並引入瞭如下依賴:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5  
 6     <groupId>com.forezp</groupId>
 7     <artifactId>service-ribbon</artifactId>
 8     <version>0.0.1-SNAPSHOT</version>
 9     <packaging>jar</packaging>
10  
11     <name>service-ribbon</name>
12     <description>Demo project for Spring Boot</description>
13  
14  
15     <parent>
16         <groupId>com.forezp</groupId>
17         <artifactId>sc-f-chapter2</artifactId>
18         <version>0.0.1-SNAPSHOT</version>
19     </parent>
20  
21     <dependencies>
22         <dependency>
23             <groupId>org.springframework.cloud</groupId>
24             <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
25         </dependency>
26         <dependency>
27             <groupId>org.springframework.boot</groupId>
28             <artifactId>spring-boot-starter-web</artifactId>
29         </dependency>
30         <dependency>
31             <groupId>org.springframework.cloud</groupId>
32             <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
33         </dependency>
34     </dependencies>
35  
36  
37  
38 </project>

在工程的配置文件指定服務的註冊中心地址爲http://localhost:8761/eureka/,程序名稱爲 service-ribbon,程序端口爲8764。配置文件application.yml以下:

1 eureka:
2   client:
3     serviceUrl:
4       defaultZone: http://localhost:8761/eureka/
5 server:
6   port: 8764
7 spring:
8   application:
9     name: service-ribbon

在工程的啓動類中,經過@EnableDiscoveryClient向服務中心註冊;而且向程序的ioc注入一個bean: restTemplate;並經過@LoadBalanced註解代表這個restRemplate開啓負載均衡的功能。

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class ServiceRibbonApplication {
 
    public static void main(String[] args) {
        SpringApplication.run( ServiceRibbonApplication.class, args );
    }
 
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
 
}

寫一個測試類HelloService,經過以前注入ioc容器的restTemplate來消費service-hi服務的「/hi」接口,在這裏咱們直接用的程序名替代了具體的url地址,在ribbon中它會根據服務名來選擇具體的服務實例,根據服務實例在請求的時候會用具體的url替換掉服務名,代碼以下:

 1 @Service
 2 public class HelloService {
 3  
 4     @Autowired
 5     RestTemplate restTemplate;
 6  
 7     public String hiService(String name) {
 8         return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
 9     }
10  
11 }

寫一個controller,在controller中用調用HelloService 的方法,代碼以下:

 1  
 2 @RestController
 3 public class HelloControler {
 4  
 5     @Autowired
 6     HelloService helloService;
 7  
 8     @GetMapping(value = "/hi")
 9     public String hi(@RequestParam String name) {
10         return helloService.hiService( name );
11     }
12 }

在瀏覽器上屢次訪問http://localhost:8764/hi?name=forezp,瀏覽器交替顯示:

hi forezp,i am from port:8762

hi forezp,i am from port:8763

這說明當咱們經過調用restTemplate.getForObject(「http://SERVICE-HI/hi?name=「+name,String.class)方法時,已經作了負載均衡,訪問了不一樣的端口的服務實例。

4、此時的架構

此時架構圖.png

  • 一個服務註冊中心,eureka server,端口爲8761
  • service-hi工程跑了兩個實例,端口分別爲8762,8763,分別向服務註冊中心註冊
  • sercvice-ribbon端口爲8764,向服務註冊中心註冊
  • 當sercvice-ribbon經過restTemplate調用service-hi的hi接口時,由於用ribbon進行了負載均衡,會輪流的調用service-hi:8762和8763 兩個端口的hi接口;

源碼下載:https://github.com/forezp/SpringCloudLearning/tree/master/sc-f-chapter2

5、參考資料

本文參考瞭如下:

http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html

業餘草微信公衆號

感謝您的關注!可加QQ1羣:135430763,QQ2羣:454796847,QQ3羣:187424846。QQ羣進羣密碼:xttblog,想加微信羣的朋友,能夠微信搜索:xmtxtt,備註:「xttblog」,添加助理微信拉你進羣。備註錯誤不會贊成好友申請。再次感謝您的關注!後續有精彩內容會第一時間發給您!原創文章投稿請發送至532009913@qq.com郵箱。商務合做可添加助理微信進行溝通!

相關文章
相關標籤/搜索