文章目录
- 1. 单体架构
- 2. 分布式架构
- 3. 微服务技术对比
- 4. 微服务案例
- 4.1 运行SpringCloud
- 4.2 微服务远程调用
1. 单体架构
单体架构:将业务的所有功能集中在一个项目中开发,打成一个包部署。
优点:架构简单、部署成本低
缺点:耦合度高
比如说有一个APP,包含订单模块、用户功能、商品功能、支付功能,对于单体架构而言,这四个功能就是在一个项目文件中开发,打包后也就成为了一个项目文件。
2. 分布式架构
分布式架构:根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务。
优点:降低服务耦合,有利于服务升级拓展
微服务是一种经过良好架构设计的分布式架构方案,微服务架构特征:
- 单一职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发
- 面向服务:微服务对外暴露业务接口
- 自治:团队独立、技术独立、数据独立、部署独立
- 隔离性强:服务调用做好隔离、容错、降级,避免出现级联问题
比如说将上面单体架构的四个功能放在微服务这里开发的话,那么四个业务功能就需要四个服务器来运行,每个功能都有自己的数据库,当然也可能是四个集群来运行,当然,这样的话也会有很多问题需要解决,比如,这样的模式想要在用户模块中访问订单模块,就需要请求另一台服务器,这就会涉及到远程请求的问题等等。
3. 微服务技术对比
比较项 | Dubbo | SpringCloud | SpringCloudAlibaba |
注册中心 | zookeeper、Redis | Eureka、Consul | Nacos、Eureka |
服务器远程调用 | Dobbo协议 | Feign(http协议) | Dubbo、Feign |
配置中心 | 无 | SpringCloudConfig | SpringCloudConfig、Nacos |
服务网关 | 无 | SpringCloudGateway、zuul | SpringCloudGateway、zuul |
服务监控和保护 | dubbo-admin,功能弱 | Hystix | Sentinel |
4. 微服务案例
4.1 运行SpringCloud
如果想要看微服务的具体案例,可以从这里下载(提取码1234)SpringCloud的一个小案例,用IDEA打开解压后的文件夹可以得到该案例(需要修改配置文件中的数据库密码和连接的数据库名称),这里搭建了两个微服务,一个USer,一个Order,并包含了数据库的插入文件,只需要运行两个sql文件即可得到数据库的表。
打开文件后,等待出现下面的界面,然后点击右键进行运行。
运行后,因为这个文件只写了Restful风格的查询,所以我们用查询进行测试,输入查询的Restful风格网址 http://localhost:8081/user/1
,得到查询的结果如下
4.2 微服务远程调用
输入 http://localhost:8080/order/101
可以看到如下的显示:
可以发现,上面的用户信息即user
一行是空的,因为是使用的微服务架构,订单模块只能查询订单的信息,用户模块只能查询用户的信息,订单模块中不存在用户的信息,所以是 null
,如果这里想要得到用户的信息,就必须对用户模块进行远程调用,对于远程调用,SpringCloud提供了 RestTemplate
,使用时只需要进行注册即可。
在Order的启动类中注入 RestTemplate
,如下所示:
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
// 注入依赖
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
然后将Order的 web
目录下的 OrderController
文件的返回值进行修改,修改如下:
@RestController
@RequestMapping("order")
public class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private RestTemplate restTemplate;
@GetMapping("{orderId}")
public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
// 根据id查询订单并返回
Order order = orderService.queryOrderById(orderId);
// 另一个微服务的地址
String url = "http://localhost:8081/user/" + order.getUserId();
// 后面的 User.class 是指将得到的json数据变为User这个实体的类型
User forObject = restTemplate.getForObject(url, User.class);
order.setUser(forObject);
return order;
}
}
再次调用 http://localhost:8080/order/101
,可以看到显示的信息如下
实现了对用户这个功能的微服务的远程调用。