Spring Cloud 服务通信
同步通信:
- dobbo 通过 RPC 远程调用。
- spring cloud 通过 REST 接口调用。
异步通信:
- 通过消息对列,如:RabbitMQ,Kafka,ActiveM 等。
本文主要介绍 Spring Cloud 使用 RestTemplate / OpenFeign 进行 REST 接口调用。
RestTemplate
通过 RestTemplate 进行调用
1
2
3
4
5
6
7
8
9
| public ProductInfo getProductMsg(String id) {
RestTemplate restTemplate = new RestTemplate();
ProductInfo response = restTemplate.getForObject(
"http://example.com/product/info", // 远程调用地址
ProductInfo.class, // response 类型
id // 需要传递的参数
);
return response;
}
|
利用 LoadBalancerClient 获取信息
1
2
3
4
5
6
7
8
9
10
11
12
| @Autowired
private LoadBalancerClient loadBalancerClient;
public ProductInfo getProductMsg(String id) {
RestTemplate restTemplate = new RestTemplate();
ServiceInstance serviceInstance = loadBalancerClient.choose("PRODUCT");
// 利用 loadBalancerClient 通过应用名(spring.application.name)获取信息
String url = String.format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort()) + "/product/info";
ProductInfo response = restTemplate.getForObject(url, ProductInfo.class, id);
return response;
}
|
利用 LoadBalance 在 RestTemplate 中直接使用应用名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| class RestTemplateConfig {
@Bean
@LoadBalance
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
---
@Autowired
private RestTemplate restTemplate;
public ProductInfo getProductMsg(String id) {
// 利用 @LoadBalance 可以在 RestTemplate 中使用应用名称
ProductInfo response = restTemplate.getForObject("http://PRODUCT/product/msg", ProductInfo.class, id);
return response;
}
|
OpenFeign (推荐)
引入依赖
1
2
3
4
| <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
|
添加启动注解
1
2
3
4
5
6
7
8
9
10
| import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@SpringBootApplication
@EnableDiscoveryClient
public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args);
}
}
|
具体实现
现在有两个服务,分别为 Prodcut 和 Order 。
需求: Order 服务中,客户进行了下单操作后,调用 Product(Feign) 的进行减库存操作。
1
2
3
4
5
6
7
8
9
10
11
12
| public class DecreaseStockInput {
// ...
}
---
@FeignClient(name = "product") // name: 远程服务名(Spring.application.name)
public interface ProductClient {
@RequestMapping(value = "/product/decrease_stock")
void decreaseStock(@RequestBody List<DecreaseStockInput> decreaseStockInputList);
}
|
- Order 服务中,对 Product Client 进行调用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| @Service
public class OrderServiceImpl implements OrderService {
// 注入的为 Product 中的 ProductClient
// 通过依赖的方式
@Autowired
private ProductClient productClient;
public OrderDTO create(OrderDTO orderDTO) {
// ...
// 调用 Product 服务中的 api 进行减库存操作
productClient.decreaseStock(decreaseStockInputList);
// ...
}
}
|