目录
在order-service的OrderApplication中注册RestTemplate
修改order-service中的OrderService的queryOrderById方法
服务拆分
服务拆分注意事项
- 单一职责:不同微服务,不要重复开发相同业务
- 数据独立:不要访问其它微服务的数据库
- 面向服务:将自己的业务暴露为接口,供其它微服务调用
idea导入工程项目cloud-demo
项目结构
cloud-demo
order-service -根据id查询用户订单
user-service -根据id查询用户
UserService逻辑代码
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id) {
return userService.queryById(id);
}
OrderService逻辑代码
@GetMapping("{orderId}")
public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
// 根据id查询订单并返回
return orderService.queryOrderById(orderId);
}
引入数据库
项目运行截图
总结
- 微服务需要根据业务模块拆分,做到单一职责,不要重复开发相同业务
- 微服务可以将业务暴露为接口,供其它微服务使用
- 不同微服务都应该有自己独立的数据库
远程调用
需求分析
根据订单id查询订单的同时,把订单所属的用户信息一起返回
目前问题分析
根据前面运行的项目,我们会发现当我们调用订单信息的时候,user返回值为null
远程调用方式分析
- 订单模块向用户模块发送用户id查询用户信息
- 订单模块查询到的订单信息结合用户模块返回回来的用户信息
实践
在order-service的OrderApplication中注册RestTemplate
/**
* 创建RestTemplate并注入Spring容器
* @return
*/
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
修改order-service中的OrderService的queryOrderById方法
未修改
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 4.返回
return order;
}
}
修改后
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
//2.利用RestTemplate发送http请求,查询用户
String url = "http://localhost:8081/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
//3.封装User到Order
order.setUser(user);
// 4.返回
return order;
}
}
重启OrderApplication
就可以发现在查询订单信息的时候同时返回了用户信息
总结
微服务调用方式
- 基于RestTemplate发起的http请求实现远程调用
- http请求做远程调用是与语言无关的调用,只要知道对方的ip、端口、接口路径、请求参数即可。
提供者与消费者
- 服务提供者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)
- 服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)
思考
服务A调用服务B,服务B调用服务C,那么服务B是什么角色?
B既是提供者也是消费者
总结
服务调用关系
- 服务提供者:暴露接口给其它微服务调用
- 服务消费者:调用其它微服务提供的接口
- 提供者与消费者角色其实是相对的
- 一个服务可以同时是服务提供者和服务消费者