一起來學 SpringCloud 之服務間調用
前言
大家好,一直以來我都本着用最通俗的話理解核心的知識點, 我認爲所有的難點都離不開 「基礎知識」 的鋪墊。目前正在出一個SpringCloud
長期系列教程,從入門到進階, 篇幅會較多~
適合人羣
-
有一定的 Java 基礎
-
想嘗試微服務開發
-
有 SpringBoot 開發基礎
-
想學習或瞭解 SpringCloud
-
想提高自己的同學
「大佬可以繞過 ~」
背景
如果你是一路看過來的,很高興你能夠耐心看完。之前帶大家學了Springboot
這門框架,熟練掌握了單體應用
的開發,如今微服務
開發盛行,對我們的技術要求也是越來越高,薪資也是令人興奮。這個系列將會帶大家學習SpringCloud
微服務開發,我會帶大家一步一步的入門,耐心看完你一定會有收穫
~
情景回顧
上期帶大家一起認識了Nacos
以及帶大家體驗了一下它作爲配置中心和註冊中心的使用,本期就帶大家結合註冊中心
來進行服務的遠程調用,首先學習一下基於rest
的遠程調用RestTemplate
,我們一起來看一下吧~
配置 RestTemplate
先配置一下它,其實RestTemplate
並不是Cloud
的產物,它在org.springframework.web.client
下的一個類,也就是說我們的單體應用比如單獨的SpringBoot
也可以用的,我們可以用它去進行http
請求調用
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory clientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(6000);
factory.setConnectTimeout(3000);
return factory;
}
}
RestTemplate 常用方法講解
爲了方便測試,我們在項目中新增兩個模塊, 一個是consumer
一個是producer
, 項目大家自己建,同樣需要把服務註冊到 Nacos 中, RestTemplateConfig
放到consumer
中,因爲它是調用端
producer
在producer
下新建一個HelloController
@RestController
@RequestMapping("/hello")
public class HelloController {
@GetMapping("/app/{id:\\d+}")
@ResponseBody
public String hello1(@PathVariable String id) {
return "hello " + id;
}
@PostMapping("/app/post")
@ResponseBody
public User hello2(@RequestBody User u) {
return u;
}
}
- User 類
@Data
public class User {
private String username;
}
consumer
同樣的,我們也新建一個HelloController
, 我們之前講過,我們直接使用ip+port
的方式也是可以直接調用的,但是我們有更好的方案,那麼如何去結合註冊中心使用呢?讓我們直接可以通過服務名
就可以調用呢?這裏我們只需要改一下RestTemplateConfig
, 只需要加一個@LoadBalanced
的註解就可以了
@Bean
@LoadBalanced // 這樣可以使用服務對象調用 http://provicer/app/hello
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
如果我想知道服務地址是啥,有什麼辦法可以拿到嗎?我們這裏可以通過服務發現獲取服務提供者的信息
@GetMapping("/discoverSvrInfo")
@ResponseBody
public URI getSvrUrl() throws Exception {
// 如果是多個服務提供者
ServiceInstance serviceInstance;
if(true) {
List<ServiceInstance> services = discoveryClient.getInstances("provider");
serviceInstance = services.size() > 0 ? services.get(0) : null;
}else {
serviceInstance = loadBalancerClient.choose("provider");
}
// 發起調用
// 1. 不同命名空間下 調用,會導致找不到實例
if(serviceInstance == null) {
throw new Exception("未獲取到實例");
}
return serviceInstance.getUri();
}
大家可以自己打斷點,看看裏邊都有些啥。有了基本的認識之後,下邊我們就來整一下吧
發起 GET 請求
- 通過實體類
@RequestMapping("/hello/user/{id:\\d+}")
@ResponseBody
public User hello1(@PathVariable String id) {
User u = restTemplate.getForEntity("http://provider/hello/app/{name}", User.class, id).getBody();
return u;
}
- 通過 Map
Map<String, Object> params = new HashMap<>();
params.put("name", id);
u = restTemplate.getForEntity("http://provider/hello/app/{name}", User.class, params).getBody();
發起 POST 請求
Map<String, String> us = new HashMap<>();
us.put("username", "java rest api -- ");
us.put("username", us.get("username") + id);
u = restTemplate.postForObject("http://provider/hello/app/post", us, User.class);
同樣的,它也有 postForObject postForEntity postForLocation
, 方法跟get
方式類似, 大家可以自己試一下
結束語
本期到這裏就結束了, 總結一下,本節主要講了,服務之間如何進結合服務發現機制
進行調用,我們通過基於rest
方式的調用,學習了restTemplate
的用法,最後完成了一個小例子, 建議大家自己多去嘗試 ~
項目源碼 (源碼已更新 歡迎 star⭐️)
-
springboot-all
-
地址
: https://github.com/qiuChengleiy/springboot-all.git
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/E0b2RCa45w5q8qCWS4wTzQ