歡迎來到SpringCloud的江湖,在本章中,我們將向大家傳授如何創建SpringCloud的父子項目架構。
知識無止境,故事有好壞,文章純屬虛構,歡迎大家吐槽。
行走江湖,沒點伎倆傍身怎麼能行。本章牽扯到的技術以及工具如下:
Intellij Idea 2018.1
JDK 8
MAVEN 3.2.2
SpringBoot 1.5.13.RELEASE
Spring-Cloud Edgware.SR3
Fegin聲明式調用
Ribbon負載均衡
RestTemplate服務調用
上一回說到Feign,Fegin的底層使用了Http請求,Ribbon做負載均衡。那麼本篇就驗證下Fegin是否使用了負載均衡。然後講解使用RestTemplate的請求服務的時候,如何使用Ribbon負載均衡。
本文基於探祕SpringCloud系列《第三篇章:使用Fegin聲明式服務調用》一文繼續延伸。
Ribbon的概念
Ribbon是一個客戶端負載均衡器,它可以很好的控制HTTP和TCP客戶端的行爲。Feign已經使用Ribbon,所以如果您使用@FeignClient,則本篇也適用。
Ribbon中的中心概念是指定客戶端的概念。每個負載均衡器都是這個組件的一部分,它們一起工作來連接到服務器,
並且它們全體都有一個給定的名字。
SpringCloud使用RibbonClientConfguration在ApplicationContext中創建一個新的全體,這包含ILoadBalancer,RestClient和ServerListFilter。
測試Fegin調用使用了負載均衡
- 在user-service模擬循環調用pub-service的服務。
添加MoreUserGoPubController.java
package com.maple.user.controller;
import com.maple.user.fegin.PubServiceFegin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 模擬大量用戶去酒館消費
* @author ZhangFZ
* @date 2020-1-15 19:39
*/
@RestController
@RequestMapping("/moreUserGoPubController")
public class MoreUserGoPubController {
private final PubServiceFegin pubServiceFegin;
@Autowired
public MoreUserGoPubController(PubServiceFegin pubServiceFegin) {
this.pubServiceFegin = pubServiceFegin;
}
@GetMapping("/moreUserGoPub")
public void moreUserGoPub(){
for (int i = 0; i < 10; i++) {
String speak = "小二,來兩壇上等的" + i + "鍋頭,兩斤牛肉,一隻烤羊腿";
System.out.println("【發送消息】:" + speak);
String result = pubServiceFegin.serviceUser(speak);
System.out.println("【收到小二回話】:" + result);
}
}
}
- 將pub-service啓動兩個服務,修改application.yml的server.port分別爲8001和8002
如何在同一個idea裏面同一個服務同時啓動多次
啓動eureka-server、user-service、pub-service
修改pub-service的application.yml中的server.port分別爲8002,PubServiceApplication-slave
瀏覽器Get請求:http://127.0.0.1:8000/moreUserGoPubController/moreUserGoPub
測試結果如下:
user-service視角:
pub-service視角:
pub-service-slave視角:
由測試結果可知,user-service在使用Fegin調用pub-service時,輪詢調用。可見,Fegin使用了負載均衡。
感興趣的同學可以查閱Fegin的源碼,看一下Fegin是怎麼結合Ribbon進行負載均衡調用的。
RestTemplate進行服務間調用使用Ribbon
上面演示了Fegin調用時使用了Ribbon負載均衡,那麼RestTemplate調用服務時怎麼使用Ribbon呢?下面讓我們一起體驗一下。
RestTemplate使用Ribbon很簡單,只需要在RestTemplate配置處添加@LoadBalanced註解即可,然後請求的時候使用註冊在Eureka服務名進行請求。
首先配置RestTemplate,在user-service添加config目錄,添加RestTemplateConfig.java
package com.maple.user.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
* @author ZhangFZ
* @date 2020-1-16 10:32
*/
@Configuration
public class RestTemplateConfig {
/**
* 註解:@LoadBalanced配置啓用Ribbon負載均衡
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory factory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
//單位爲ms
factory.setReadTimeout(15000);
//單位爲ms
factory.setConnectTimeout(15000);
return factory;
}
}
在MoreUserGoPubController.java添加通過RestTemplate調用pub-service的方法
package com.maple.user.controller;
import com.maple.user.fegin.PubServiceFegin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
/**
* 模擬大量用戶去酒館消費
* @author ZhangFZ
* @date 2020-1-15 19:39
*/
@RestController
@RequestMapping("/moreUserGoPubController")
public class MoreUserGoPubController {
private final RestTemplate restTemplate;
@Autowired
public MoreUserGoPubController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
/**
* 模擬RestTemplate大量用戶去酒館
*/
@GetMapping("/moreUserGoPubRest")
public void moreUserGoPubRest(){
for (int i = 0; i < 10; i++) {
String speak = "通過RestTemplate傳音----> 小二,來兩壇上等的" + i + "鍋頭,兩斤牛肉,一隻烤羊腿";
System.out.println("【發送消息】:" + speak);
//調用在Eureka註冊的實例,對應調用的spring.application.name,不區分大小寫
String url = "http://PUB-SERVICE/pubServiceUser/serviceUser?speak={speak}";
Map<String, Object> map = new HashMap<>(16);
map.put("speak", speak);
String result = restTemplate.getForEntity(url, String.class, map).getBody();
System.out.println("【收到小二回話】:" + result);
}
}
}
這樣就可以了,讓我們一起看一下測試結果
user-service視角:
pub-service視角:
pub-service-slave視角:
有的同學會有疑問,你怎麼知道是@LoadBalanced
註解起的作用呢?
我們把@LoadBalanced
註解去掉試一下。請求找不到服務信息。
愛提問題的同學又來了,那你怎麼知道@LoadBalanced
使用的是Ribbon?
我們一起看一下@LoadBalanced
的源碼
本章到此結束。後續文章會陸續更新,文檔會同步在CSDN和GitHub保持同步更新。
CSDN:https://blog.csdn.net/qq_34988304/category_8820134.html
Github文檔:https://github.com/hack-feng/Java-Notes/tree/master/src/note/SpringCloud
GitHub源碼:https://github.com/hack-feng/Spring-Cloud-Edgware.git