(此次创建的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】,发现可以正常访问,如下图: