服务间的通信有HTTP和RPC两种方式,常见的Dubbo就是使用的RPC协议,SpringCloud使用HTTP进行服务间的通信。
这里我们主要了解一下SpringCloud中服务间festful两种调用方式。
1、RestTemplate
2、Feign
RestTemplate第一种方式
在商品服务中定义一个ServerController
@RestController
public class ServerController {
@RequestMapping("/msg")
public String message(){
return "this is a message";
}
}
在订单服务中定义一个ClientController
@RestController
@Slf4j
public class ClientController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@RequestMapping("getproductMsg")
public String getProductMsg() {
//1、RestTemplate第一种方式
// RestTemplate restTemplate = new RestTemplate();
//第一个参数是url,第二个参数返回的类型
// String response = restTemplate.getForObject("http://localhost:9080/msg",String.class);
log.info("response={}",response);
return response;
}
}
最后通过访问 http://localhost:8080/getproductMsg ,可以得到商品接口返回的数据。
这种方式url地址是写死的,在实际项目开发过程中,项目部署地址ip是不确定的,并不推荐使用。
RestTemplate第二种方式
通过SpringCloud中的LoadBalancerClient 获取服务名的ip和端口
@RestController
@Slf4j
public class ClientController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@RequestMapping("getproductMsg")
public String getProductMsg() {
RestTemplate restTemplate = new RestTemplate();
ServiceInstance serviceInstance = loadBalancerClient.choose("PRODUCT");
String url = String.format("http://%s:%s",serviceInstance.getHost(),serviceInstance.getPort()+"/msg");
log.info("url={}",url);
//第一个参数是url,第二个参数返回的类型
String response = restTemplate.getForObject(url,String.class);
log.info("response={}",response);
return response;
}
}
RestTemplate第三种方式
将RestTemplate 配置一个Bean,并添加 @LoadBalanced 注解
@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
restTemplate中直接通过服务名请求
@RestController
@Slf4j
public class ClientController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("getproductMsg")
public String getProductMsg() {
// 3、第三种方式
String response = restTemplate.getForObject("http://PRODUCT/msg",String.class);
log.info("response={}",response);
return response;
}
}
Feign服务通信
1、在调用服务的客户端导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、在启动类上添加注解@EnableFeignClients
。
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
3、客户端新建一个接口类
@FeignClient注解中name属性的值为服务名。
通过@GetMapping寻找对应的接口。
@FeignClient(name = "product")
public interface ProductClient {
@GetMapping("/msg")
String productMsg();
}
4、controller调用
@RestController
@Slf4j
public class ClientController {
@Autowired
private ProductClient productClient;
@RequestMapping("getproductMsg")
public String getProductMsg() {
String response = productClient.productMsg();
log.info("response={}",response);
return response;
}
}