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

SpringCloud-微服务拆分 - 努力-

一、环境准备

1.1 docker mysql 环境:

先创建docker中数据库容器:

# 创建网络
docker network create sc-netdocker run -d \--name mysql \-p 3306:3306 \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=1234 \-v ./mysql/data:/var/lib/mysql \-v ./mysql/conf:/etc/mysql/conf.d \-v ./mysql/init:/docker-entrypoint-initdb.d \--network sc-net \mysql

挂起之后启动有问题,无法连接容器,解决方案:

# 关闭防火墙
stytemctl stop firewalld
# 禁止开机启动防火墙
stytemctl disable firewalld# 修改ipv4转发状态
vi /usr/lib/sysctl.d/00-system.conf# 添加信息
net.ipv4.ip_forward = 1# 保存退出后,重启网络服务
stytemctl restrat network# 将docker 的网络接口设置为不被NetworkManager
vi /etc/NetworkManager/conf.d/10-unmanage-docker-interfaces.conf# 文件中添加如下内容
[keyfile]# 重启网络
stytemctl restart NetworkManager
# 重启docker
stytemctl restart docker
# 启动相应的容器
docker restart mysql

1.2 启动后端项目

1.按下ALT + 8键打开services窗口,新增一个启动项:
找到Spring Boot:
在这里插入图片描述

2.在运行之前,做个简单配置:在Application上点击鼠标右键,会弹出窗口,然后选择Edit Configuration
在这里插入图片描述

在弹出窗口中配置SpringBoot的启动环境为 local

在这里插入图片描述

1.3 启动前端项目

# 启动nginx
start nginx.exe
# 停止
nginx.exe -s stop
# 重新加载配置
nginx.exe -s reload
# 重启
nginx.exe -s restart

注意:nginx.exe 不要双击启动,而是打开cmd窗口,通过命令行启动。停止的时候也一样要是用命令停止。如果启动失败不要重复启动,而是查看logs目录中的error.log日志,查看是否是端口冲突。如果是端口冲突则自行修改端口解决。

二、测试单体架构

重新启动项目,目前有两个接口是无需登录即可访问的:

  • http://localhost:8080/hi
  • http://localhost:8080/search/list

http://localhost:8080/search/list接口:
在这里插入图片描述
http://localhost:8080/hi接口:
在这里插入图片描述

接下来,我们假设/hi这个接口是一个并发较高的热点接口,我们通过Jmeter来模拟5000个用户不停访问。
使用JMeter打开测试文件;

在这里插入图片描述

@RestController
@RequestMapping("hi")
public class HelloController {private final Map<String, AtomicInteger> countMap = new HashMap<>();}

这个脚本会开启500个线程并发请求http://localhost/hi这个接口。由于该接口存在执行耗时,这就导致服务端每秒能处理的请求数量有限,最终会有越来越多请求积压,直至Tomcat资源耗尽。这样,其它本来正常的接口(例如/search/list)也都会被拖慢,甚至因超时而无法访问了。

在这里插入图片描述

我们测试一下,启动测试脚本,然后在浏览器访问http://localhost:8080/search/list这个接口,会发现响应速度非常慢:

如果进一步提高/hi这个接口的并发,最终会发现/search/list接口的请求响应速度会越来越慢。

可见,单体架构的可用性是比较差的,功能之间相互影响比较大。

单体架构的问题:

  • 团队协作成本高:由于所有模块都在一个项目工程中,不同模块的代码之间物理边界越来越模糊。最终要把功能合并到一个分支,你绝对会陷入到解决冲突的泥潭之中。
  • 系统发布效率低:任何模块变更都需要发布整个系统,而系统发布过程中需要多个模块之间制约较多,需要对比各种文件,任何一处出现问题都会导致发布失败,往往一次发布需要数十分钟甚至数小时。
  • 系统可用性差:单体架构各个功能模块是作为一个服务部署,相互之间会互相影响,一些热点功能会耗尽系统资源,导致其它服务低可用。

三、业务分析

1.登录
登录成功后返回jwt令牌。
2.搜索商品
在首页搜索框输入关键字,点击搜索即可进入搜索列表页面:

3.购物车
在搜索到的商品列表中,点击按钮加入购物车,即可将商品加入购物车:
加入成功后即可进入购物车列表页,查看自己购物车商品列表:
同时这里还可以对购物车实现修改、删除等操作。
其中,查询购物车列表时,由于要判断商品最新的价格和状态,所以还需要查询商品信息,业务流程如下:
在这里插入图片描述

4.下单:
在购物车页面点击结算按钮,会进入订单结算页面:

点击提交订单,会提交请求到服务端,服务端做3件事情:

  • 创建一个新的订单。
  • 扣减商品库存。
  • 清理购物车中商品。

5.支付

四、服务拆分原则

微服务拆分时粒度要小,这其实是拆分的目标。具体可以从两个角度来分析:

  • 高内聚:每个微服务的职责要尽量单一,包含的业务相互关联度高、完整度高。
  • 低耦合:每个微服务的功能要相对独立,尽量减少对其它微服务的依赖,或者依赖接口的稳定性要强。

高内聚首先是单一职责,但不能说一个微服务就一个接口,而是要保证微服务内部业务的完整性为前提。目标是当我们要修改某个业务时,最好就只修改当前微服务,这样变更的成本更低。

一旦微服务做到了高内聚,那么服务之间的耦合度自然就降低了。

当然,微服务之间不可避免的会有或多或少的业务交互,比如下单时需要查询商品数据。这个时候我们不能在订单服务直接查询商品数据库,否则就导致了数据耦合。而应该由商品服务对应暴露接口,并且一定要保证微服务对外接口的稳定性(即:尽量保证接口外观不变)。虽然出现了服务间调用,但此时无论你如何在商品服务做内部修改,都不会影响到订单微服务,服务间的耦合度就降低了。

明确了拆分目标,接下来就是拆分方式了。我们在做服务拆分时一般有两种方式:

  • 纵向拆分。
  • 横向拆分。

所谓纵向拆分,就是按照项目的业务功能模块来拆分。例如黑马商城中,就有用户管理功能、订单管理功能、购物车功能、商品管理功能、支付功能等。那么按照功能模块将他们拆分为一个个服务,就属于纵向拆分。这种拆分模式可以尽可能提高服务的内聚性。

横向拆分是看各个功能模块之间有没有公共的业务部分,如果有将其抽取出来作为通用服务。例如用户登录是需要发送消息通知,记录风控数据,下单时也要发送短信,记录风控数据。因此消息发送、风控数据记录就是通用的业务功能,因此可以将他们分别抽取为公共服务:消息中心服务、风控管理服务。这样可以提高业务的复用性,避免重复开发。同时通用业务一般接口稳定性较强,也不会使服务之间过分耦合。

此项目业务按照纵向拆分,可以分为以下几个微服务:

  • 商品服务。
  • 购物车服务。
  • 用户服务。
  • 订单服务。
  • 支付服务。

一般微服务项目有两种不同的工程结构:

  • 完全解耦:每一个微服务都创建为一个独立的工程,甚至可以使用不同的开发语言来开发,项目完全解耦。
    • 优点:服务之间耦合度低。
    • 缺点:每个项目都有自己的独立仓库,管理起来比较麻烦。
  • Maven聚合:整个项目为一个Project,然后每个微服务是其中的一个Module。
    • 优点:项目代码集中,管理和运维方便。
    • 缺点:服务之间耦合,编译时间较长。

拆分商品、购物车服务

4.1 商品微服务

1)定义SpringBoot、SpringCloud的依赖。


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.it</groupId><artifactId>scmall</artifactId><packaging>pom</packaging><version>1.0.0</version><modules><module>sc-common</module><module>sc-service</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version><relativePath/></parent>
<properties><mybatis-plus.version>3.4.3</mybatis-plus.version><hutool.version>5.8.11</hutool.version><mysql.version>8.0.23</mysql.version>
</properties><!-- 对依赖包进行管理 -->
<dependencyManagement><dependencies><!--spring cloud--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!--spring cloud alibaba--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency><!-- 数据库驱动包管理 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- mybatis plus 管理 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><!--hutool工具包--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency></dependencies>
</dependencyManagement>
<dependencies><!-- lombok 管理 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${org.projectlombok.version}</version></dependency><!--单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies><build><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>11</source> <!-- depending on your project --><target>11</target> <!-- depending on your project --></configuration></plugin></plugins></pluginManagement></build>
</project>

2)创建模块。

3)添加依赖。

item-servicepom.xml文件参考:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.it</groupId><artifactId>scmall</artifactId><version>1.0.0</version></parent><artifactId>item-service</artifactId><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target></properties><dependencies><!--common--><dependency><groupId>com.it</groupId><artifactId>sc-common</artifactId><version>1.0.0</version></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--数据库--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!--单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies><build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

4)创建启动引导类。

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@MapperScan("com.scmail.item.mapper")
@SpringBootApplication
public class ItemApplication {public static void main(String[] args) {SpringApplication.run(ItemApplication.class, args);}
}

5)复制配置文件。
复制 sc-service 中的 application.yml、application-local.yml、application-dev.yml 文件到 item-service 项目的 resources目录如下:

修改application.yml 文件,如下:

6)复制代码。
在这里插入图片描述

7)创建数据库表。
先创建docker中数据库容器:

# 创建网络
docker network create hm-netdocker run -d \--name mysql \-p 3306:3306 \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=root \-v ./mysql/data:/var/lib/mysql \-v ./mysql/conf:/etc/mysql/conf.d \-v ./mysql/init:/docker-entrypoint-initdb.d \--network hm-net \mysql

8)测试:
接下来,就可以启动测试了;复制一个启动项并修改如下:
Copy Configuration : project 选item-service。
在这里插入图片描述

然后修改:修改完成后如下:
active Profiles :Local。
在这里插入图片描述
访问 http://localhost:8081/search/list

在这里插入图片描述

4.2 购物车微服务

http://www.jsqmd.com/news/486583/

相关文章:

  • # 发散创新:基于RBAC模型的权限管理系统在Go语言中的高效实现在现代软件
  • 从Lattice到EM:自动驾驶规划算法的演进与场景适配深度解析
  • CASS3D实战:OSGB模型在测绘中的高效应用
  • 2026年3c认证插座有哪些品牌?五大可靠品牌推荐 - 品牌排行榜
  • S7-1200与S7-200 SMART通信实战:5分钟搞定PROFINET配置(含TSAP避坑指南)
  • draw.io:零基础也能上手的免费流程图绘制利器
  • 华为AC+AP融合组网:基于有线口配置实现多楼层统一接入与策略管理
  • ArcGIS Pro模型构建器实战:从零搭建选址分析模型(附完整GDB配置流程)
  • iPhone变身移动硬盘:iTunes文件共享疑难全解析与高效操作指南
  • 从源码到实践:PODOFO动态库编译与PDF生成测试全流程指南
  • PP-DocLayoutV3模型微调入门:使用自定义数据提升特定场景精度
  • 【实战进阶】jQuery+Bootstrap动态交互设计:从响应式布局到用户体验优化
  • ADS板材加工全流程:从DXF导出到PCB设计实战
  • K-prototypes混合聚类教程:当你的数据既有年龄又有购物习惯时该怎么办?
  • PureScript v0.15.16发布,多方面优化升级
  • Altium文件高效解析工具:Python-Altium零门槛使用指南
  • Qwen3-0.6B-FP8精彩案例:数学悖论解析+诗歌创作+代码生成三连击
  • Ostrakon-VL-8B赋能Java应用:SpringBoot集成多模态AI服务实战
  • MPI并行编程避坑指南:5个常见内存错误及修复方法(附代码示例)
  • 福建大佬隐秘布局,科技投资新风向显现
  • Qwen3-4B-Thinking-GGUF部署教程:GPU多实例MIG模式下资源隔离部署
  • 2026防脱生发加盟品牌市场分析:创业机遇与品牌选择 - 品牌排行榜
  • 5大核心功能解析:让PPTist用户效率提升60%的开源演示方案
  • Mac百度网盘下载速度革新:3大突破让你告别漫长等待
  • Zemax实战:3分钟看懂像散现象与ASTI操作数的正确用法
  • 国内深圳知名光学滤光轮/光阑座/激光器外壳/扫描振镜基座/空间相机镜筒/调焦旋钮卫星激光通信终端零件CNC加工厂家推荐 - 余文22
  • 操作系统核心概念解析:从基础原理到现代应用
  • IPD 集成产品开发项目管理工具测评:飞书项目、PingCode 与 ONES 深度对比
  • 避坑指南:泛微Ecology9弹窗建模数据回填常见的5个报错及解决方案
  • 华为云CentOS7安全组443端口配置全攻略:从外网访问失败到防火墙精准排查