单体架构

业务的所有功能集中在一个项目中开发,打包成一个包部署。
6f344e10fbcb4c8e9385198a5c2ed481.png
优点:架构简单、部署成本低。
缺点:团队协作成本高、系统发布效率低、系统可用性差。

由于tomcat资源有限,同一个时间可能的并发量不大,如果有一个线程有大量的请求访问,其他的线程也会收到影响。

微服务架构

微服务架构是服务化思想指导下的一套最佳实践架构方案。服务化思想:把单体架构中的功能模块拆分为多个独立的项目。
a45478ce92d8493f804f65d3cb61de66.png

SpringCloud

是最广泛的微服务框架。
2c49976ed225467f96da6b5dbe4fe874.png

微服务拆分

拆分原则

  1. 创业型项目:先采用单体项目快速开发,随着规模扩大,逐渐拆分。
  2. 确定的大型项目:资金充足,目标明确,可以直接选择微服务项目,避免后续拆分麻烦。

要做到:高内聚、低耦合。
高内聚:每个微服务的职责单一,包含的业务关联度高、完整度高。
低耦合:每个微服务的功能相对独立,尽量减少对其他服务的依赖。

拆分方式:

  • 横向拆分:抽取公共服务,提高复用性。
  • 纵向拆分:按照业务模块来拆分。

拆分服务

工程结构有两种:

  1. 独立Project:一个Project下多个Project
  2. Maven聚合:一个Project下多个module

远程调用

购物车服务里需要用到商品服务里的接口,但是此时是这两个服务已经拆分了,所以需要购物车服务向商品服务发送请求【类似于前端页面向后端发请求】
f8d891fc93dc49b1b0a24c2fd22aad96.png

方法1.RestTemplate

70b364c3b28c4956b5a785039d30df34.png

// 单体服务:
// List<ItemDTO> items = itemService.queryItemByIds(itemIds);

// 微服务远程调用:
// 1. 利用restTemplate发起http请求,得到http响应
ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
"http://localhost:8081/items?ids={ids}",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<ItemDTO>>() {
}, // 泛型的引用
Map.of("ids", CollUtil.join(itemIds, ","))
);
// 2.解析响应
if(!response.getStatusCode().is2xxSuccessful()){
return;
}
List<ItemDTO> items = response.getBody();

存在的问题:服务的调用者,在写代码的时候,还不知道服务提供者的地址。例如:商品微服务那边部署在了多台服务器,写url时,就不知道怎么写了。
2f37302c55054edb95b1d5380ac397e3.png

方法2.注册中心

通过注册中心进行服务治理,通过订阅服务和注册服务,实现服务之间的远程调用;再通过OpenFeign来发送http请求。

// 方法2.使用nacos + openFeign
// 根据服务名称,获取服务的实例列表
List<ServiceInstance> instances = discoveryClient.getInstances("item-service"); // 实例列表
if(CollUtils.isEmpty(instances)){
return;
}
List<ItemDTO> items = itemClient.queryItemByIds(itemIds);

(详细操作看:nacos注册中心 + OpenFeign远程调用