当前位置: 首页 > news >正文

SpringCloud —— 黑马商城的项目拆分和Nacos

一、前言

我们已经将黑马商城的前置知识学完(mp、docker),接下来就是要开始黑马商城项目了,这个项目本身是一个已经做好的项目,但是是单体架构,和苍穹外卖是一样的,现在我们将利用黑马商城来学习微服务,所以首先就需要拆分项目了。

在这之前,记得一定要创建一个git仓库,并且虚拟机要定期保存快照,本项目经多人实测,中途可能会出现问题(比如无法访问nacos网站等问题),而本人也经历了虚拟机崩溃的问题,所以在将来可能需要使用git回溯,如果虚拟机出问题了也需要恢复快照。

二、项目结构和拆分原则

黑马商城的项目结构是比较简单的,每一个板块都是分得比较清楚的,比如有商品模块、购物车模块、订单模块、支付模块等等......

这里我们选择将这些较为独立集中的模块拆分成项目结构中的模块(也可以直接拆成一个独立的项目,但是在学习期间不易管理),如下图所示(部分拆分)

同时需要导入不同模块所需要的表:

我们的拆分原则是:拆分出功能相对独立的模块,每一个拆分后的模块需要有自己单独的表。

三、远程调用

在拆分时我们会发现一些问题,比如购物车模块需要依赖商品模块,但是跨模块是不允许直接调用的,而且也不能直接调用,因为我们拆分项目的初衷是解耦合,使项目更好管理,如果模块之间相互依赖调用,这样和单体架构就没什么两样了,所以也就完全体现不出微服务的优势了。

所以这里我们绝对不能直接调用,这个时候就可以联想到之前苍穹外卖使使用过的HttpClient了,当时我们是使用这个工具来让客户端获取店铺信息,本质上是通过向管理端发起了一个请求,然后获取管理端传回来的响应,解析后拿到店铺状态。

这里我们暂时就不使用httpclient了,我们使用restTemplate:

首先需要注册到Bean中去,所以要一个配置类,但是由于这个配置很简单,所以我们直接写在启动类中:

@MapperScan("com.hmall.cart.mapper") @SpringBootApplication public class CartApplication { public static void main(String[] args) { SpringApplication.run(CartApplication.class, args); } @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }

使用restTemplate主要也就分为两步:

1.发送请求并接收响应

2.解析响应

private void handleCartItems(List<CartVO> vos) { // TODO 1.获取商品id Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet()); // 2.查询商品 // List<ItemDTO> items = itemService.queryItemByIds(itemIds); // 2.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.2.解析响应 if(!response.getStatusCode().is2xxSuccessful()){ // 查询失败,直接结束 return; } List<ItemDTO> items = response.getBody(); if (CollUtils.isEmpty(items)) { return; } // 3.转为 id 到 item的map Map<Long, ItemDTO> itemMap = items.stream().collect(Collectors.toMap(ItemDTO::getId, Function.identity())); // 4.写入vo for (CartVO v : vos) { ItemDTO item = itemMap.get(v.getItemId()); if (item == null) { continue; } v.setNewPrice(item.getPrice()); v.setStatus(item.getStatus()); v.setStock(item.getStock()); } }

虽然逻辑简单,但是代码确实不少,太繁琐了,所以后期我们会使用一个新技术来高度封装这些步骤,这里学习RestTemplate有助于了解封装的底层原理,所以还是需要看看的。

四、Nacos注册中心

1.简介

首先我们要知道,目前我们拆分了项目,但是其实是没有进行统一管理的,尤其是一个模块如果出现多个实例,我们根本无法达到负载均衡。

先前我们在nginx中提到了负载均衡的,大致意思就是如果一个模块是一个服务器集群,那么当多个请求访问这个服务器时,可以将请求压力分摊到每个服务器上,也就是不会一直只访问一个服务器,这就是负载均衡

为了实现这个目的,我们要引入一个管理中心——Nacos,我们可以将每个模块注册进这个管理中心,由Nacos管理,有远程调用的需求时,Nacos会自动将请求分配给目标服务器(告诉请求发起者应该请求给哪个服务器)

2.具体实现步骤

(1)创建并启动容器

首先我们要在虚拟机的Docker中用Nacos的镜像创建一个Nacos的容器:

(2)在目标模块导入依赖

<!--nacos 服务注册发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>

(3)写入配置文件

cloud: nacos: server-addr: 192.168.xxx.xxx:8848

这里就是指定Nacos容器所在的IP地址和Nacos的端口号,这样就能让SpringCloud将项目注册到Nacos中了(导入依赖的目的就是为了让这个配置生效)。

(4)测试

这里我将启动三个模块,其中有两个实例是源于一个模块,相当于模拟一个服务器集群(集群中有两台服务器)

这是就可以访问nacos的网站了,在这里就可以统一管理服务器了:

这里我们发送五次请求,看看是否实现了负载均衡:

从结果来看是实现了的,8081和8083都是被请求到了的。

五、OpenFeign

刚刚在远程调用的时候就提到了,使用restTemplate是及其不方便的,也预告了后面会封装,这个组件就是OpenFeign,它通过和SpringBoot相似的语法,减少了学习成本,让远程调用更加规范,耦合度更低,最重要的是,代码量大幅减少。

OpenFeign的底层是可以选择的,比如刚刚提到的httpclient,除此之外还要okhttp等等。

接下来讲解如何使用OpenFeign:

1.启动类

首先启动类需要开启OpenFeign:

@EnableFeignClients @MapperScan("com.hmall.cart.mapper") @SpringBootApplication public class CartApplication { public static void main(String[] args) { SpringApplication.run(CartApplication.class, args); } }

2.导入依赖

<!--openFeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependency> <!--OK http 的依赖 --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency>

3.配置

feign: okhttp: enabled: true # 开启OKHttp功能

4.创建接口

这里注意,这个接口是不需要被实现的,和Mapper接口一样,Spring会通过动态代理自动实现。

@FeignClient("item-service") public interface ItemClient { @GetMapping("/items") List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids); }

可以看到这个接口的写法和SpringBoot的语法几乎一样,所以也不再赘述,就是需要注意要在注解写明远程调用的项目名

5.远程调用

修改代码,一行代码就可以获取到item-service响应回来的数据了。

private void handleCartItems(List<CartVO> vos) { //1.获取商品id Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet()); //openfeign List<ItemDTO> items = itemClient.queryItemByIds(itemIds); if (CollUtils.isEmpty(items)) { //如果查询失败 return; } // 3.转为 id 到 item的map Map<Long, ItemDTO> itemMap = items.stream().collect(Collectors.toMap(ItemDTO::getId, Function.identity())); // 4.写入vo for (CartVO v : vos) { ItemDTO item = itemMap.get(v.getItemId()); if (item == null) { continue; } v.setNewPrice(item.getPrice()); v.setStatus(item.getStatus()); v.setStock(item.getStock()); } }
http://www.cnnetsun.cn/news/4354.html

相关文章:

  • Mini2440移植uC/OS-II笔记(一)数据结构分析
  • Mini2440移植uC/OS-II笔记(二)数据结构分析+
  • Wan2.2-T2V-A14B模型在低光照场景生成中的稳定性验证
  • Wan2.2-T2V-A14B实现动物行为自然运动的关键技术
  • Wan2.2-T2V-5B能否生成快递无人机配送过程动画?
  • 龙芯2K0300开发板终极指南:从入门到实战的10个核心技巧
  • CameraKit-Android完整指南:快速构建稳定相机应用
  • springboot非遗手作交流分享平台-计算机毕业设计源码57755
  • Wan2.2-T2V-A14B在核电站安全运行原理讲解中的应用
  • 终于大开眼界:DEEPSEEK的撒谎能力着实让我大吃一惊!!!
  • 告别设备绑定!用 VSCode+WSL+cpolar搭建跨网开发环境的实用指南
  • Rebel 终极指南:快速掌握 macOS AppKit 开发框架的完整安装配置
  • 跨平台设备监控与性能分析工具:实现多设备高效管理
  • Wan2.2-T2V-A14B支持多摄像头视角切换的智能编排
  • 7、DB2客户端连接性:从入门到实践
  • Python协程使用详解
  • Python+appium自动化测试
  • 【完整源码+数据集+部署教程】电子元件目标检测检测系统源码[一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]
  • Android 基础入门教程​​ LinearLayout(线性布局)分类
  • 笔记本电脑全内置式水冷散热设计
  • CefSharp实战宝典:从零构建高性能嵌入式浏览器应用
  • 免费无广!这款 PDF 橡皮擦,功能非常强大,办公党必藏!
  • 快速上手verl全流程实战指南:如何避开大模型强化学习配置陷阱?
  • 海外红人营销如何提升美妆转化?从认知到决策的全链路解析
  • Wan2.2-T2V-A14B在航空时刻表宣传视频中的航班动态模拟
  • PHP 8.6即将改变游戏规则:协程调度优化全曝光
  • Wan2.2-T2V-A14B模型对量子物理概念可视化的挑战应对
  • 从理论到实践:C#与Python协同开发量子算法的3步极速入门法
  • 【临床数据生存分析实战指南】:掌握R语言Cox模型构建与解读精髓
  • 云资产查询革命:用SQL统一管理多云环境的终极方案