(此次創建的Demo小案例都是基於springBoot【2.0.0.M3】,springCloud【Finchley.M2】創建的,讀者若是爲了演示正常,請務必保持版本一致)
我們知道,微服務中每一個服務之間都是相對獨立的,我們常常應該是一個單獨的服務(可以理解爲一個應用,一個單獨的進程)去訪問另外一個單獨的服務,那麼兩個服務之間又是如何通信的呢?下面我們通過講解RestTemplate的三種使用方式來說明他們之間的通信
首先我們需要創建兩個單獨的項目,這裏我們創建【product】和【order】兩個服務,order來調用product。
項目創建的過程我們這裏不再重複多說,至於如何創建可以參見【SpringCloud 之 Eureka Client 客戶端的創建與使用】因爲相對於註冊中心來說,我們創建的模塊也相當於client端
(一定要注意版本號保持一致,還有啓動類上注意添加註解【@EnableDiscoveryClient】)
第一種方式
1.product端我們新建一個controller,然後創建一個簡單的待訪問類【ClientController】
@RestController
public class ClientController {
@GetMapping("/msg")
public String msg(){
return "我是product端傳來的消息!";
}
}
啓動測試可以正常訪問
2.order端我們創建一個controller ,新建一個【OrderCotroller】
@RestController
public class OrderCotroller {
@RequestMapping("getProductMsg")
public String getProductMsg(){
RestTemplate restTemplate=new RestTemplate();
String forObject = restTemplate.getForObject("http://localhost:8080/msg", String.class);
System.out.println("我們是order調用端:"+forObject);
return forObject;
}
}
然後啓動,我們訪問 【http://localhost:8090/getProductMsg】,發現可以正常訪問,如下圖:
第二種方式
若對方是多個節點,或者說是多臺服務器做的負載均衡,我們是不知道其具體的地址的,這時候我們可以採用第二種方式
product端不變,修改我們的order端,此種方式是通過服務端的名字進行訪問的
@RestController
public class OrderController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@RequestMapping("/getProductMsg")
public String getProductMsg(){
ServiceInstance product = loadBalancerClient.choose("PRODUCT");
String host = product.getHost();
int port = product.getPort();
String formatStr = String.format("http://%s:%s", host,port)+"/msg";
RestTemplate restTemplate=new RestTemplate();
String forObject = restTemplate.getForObject(formatStr, String.class);
System.out.println("我們是order調用端:"+forObject);
return forObject;
}
}
然後啓動,我們訪問 【http://localhost:8090/getProductMsg】,發現可以正常訪問,如下圖:
第三種方式
1.新建一個【RestTemplateConfig】配置類
@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
2.然後進行引入並調用
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/getProductMsg2")
public String getProductMsg2(){
String forObject = restTemplate.getForObject("http://PRODUCT/msg", String.class);
System.out.println("我們是order調用端:"+forObject);
return forObject;
}
然後啓動,我們訪問 【http://localhost:8090/getProductMsg】,發現可以正常訪問,如下圖: