微服务学习笔记(1)——SpringCloud概述
🔥我的主页:九转苍翎⭐️个人专栏:《Java SE 》《Java集合框架系统精讲》《MySQL高手之路:从基础到高阶 》《计算机网络 》《Java工程师核心能力体系构建》《RabbitMQ理论与实践》天行健,君子以自强不息。
1.系统架构的迭代
1.1 单体架构
定义:整个应用程序的所有功能模块(如用户管理、订单管理、支付管理等)都打包在一个单一的进程中,使用同一个数据库
优点:
- 技术栈统一:开发、测试、部署简单。
- 易于开发:初期功能集中,模块间直接调用,沟通成本低
- 性能高:本地方法调用,没有网络开销
- 部署单一:只需维护一个应用
缺点:
- 代码复杂度高:随着功能增加,代码库变得庞大、耦合严重,难以理解和维护
- 技术栈固化:难以引入新的框架或语言
- 可扩展性差:无法针对特定模块进行独立伸缩,必须整体伸缩,成本高
- 部署不灵活:任何微小的修改都需要重新构建和部署整个应用,风险高、上线慢
- 可靠性风险:一个模块的bug可能导致整个系统崩溃
1.2 集群与分布式架构
定义:
- 分布式:将单体应用按业务维度拆分成多个独立的子系统,这些子系统可以部署在不同的服务器上,通过网络通信协作完成整体业务。本质上是“拆分”
集群:为了解决单点故障和性能瓶颈,将相同的单体应用部署在多台服务器上,通过负载均衡器对外提供服务。本质上是“复制”
优点:
- 高可用与高性能:通过集群实现负载均衡和故障转移
- 初步解耦:通过分布式拆分,系统在物理上分离,技术栈可以按服务选择
- 数据库拆分:可能出现分库分表,读写分离
缺点:
- 服务治理复杂:需要管理它们的地址(服务发现)、调用关系、负载均衡策略
- 通信可靠性:网络调用代替本地调用,面临超时、重试、网络故障等问题。
- 数据一致性:从单一数据库变为分布式数据库,面临分布式事务难题
- 运维复杂:需要监控、管理成百上千的服务实例,部署、配置、日志收集都变得困难
- 服务间依赖:可能形成复杂的调用链
1.3 微服务架构
定义:微服务架构是分布式架构的一种更精细、更彻底的实践。它强调将单个应用程序拆分为一组微小、自治的服务
分布式架构与微服务架构的区别:分布式架构:侧重于压力的分散,强调的是服务的分散化微服务架构:侧重于能力的分散,更强调服务的专业化和精细分工
2.SpringCloud概述
2.1 微服务、SpringCloud与SpringBoot的关系
微服务是架构思想:强调将单个应用拆分为一组小型的、独立部署的服务,每个服务围绕业务能力构建。但思想落地需要工具——服务发现、配置中心、负载均衡等这些分布式系统要解决的问题,微服务本身并不提供Spring Cloud是构建微服务架构的一套解决方案:规定了应用间协作的标准方式,涵盖以下核心组件- 服务发现:互相知道在哪里
- 远程调用:支持服务间接口调用
- 负载均衡:将请求/流量按照规定的算法分配到处理同一业务的不同机器上
- 配置管理:外部化动态配置和集中化管理配置
- API网关:请求的统一入口
SpringBoot是构建单个微服务的基础框架:通过自动配置、起步依赖和嵌入式容器等特性,快速创建独立运行的Spring应用
2.2 SpringCloud的实现方式
Spring Cloud 本身是一套标准/规范,具体实现方式主要分为以下几种技术选型方案
站在Java的视角进行类比的话,Spring Cloud相当于定义了一堆interface,下述的Spring Cloud Netflix/Spring Cloud Alibaba相当于同一接口的不同实现类
| 组件角色 | Spring Cloud Netflix | Spring Cloud Alibaba | Spring Cloud 官方原生 |
|---|---|---|---|
| 服务发现 | Eureka | Nacos | Consul / Zookeeper |
| 负载均衡 | Ribbon | Ribbon / Spring Cloud LoadBalancer | Spring Cloud LoadBalancer |
| 远程调用 | Feign | Feign / RestTemplate | OpenFeign |
| 熔断降级 | Hystrix | Sentinel | Resilience4j |
| API 网关 | Zuul 1.x | Spring Cloud Gateway | Spring Cloud Gateway |
| 配置中心 | Spring Cloud Config | Seata | Spring Cloud Config / Consul / Nacos |
2.3 版本对应关系
SpringCloud:SpringCloud
SpringCloud Alibaba:SpringCloud Alibaba
3.父子工程搭建
3.1 项目结构
3.2 依赖导入和pom文件解析
3.2.1 spring-cloud-blog
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="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>org.example</groupId><artifactId>spring-cloud-blog</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules><module>modules</module></modules><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><java.version>17</java.version><mybatis.version>3.0.3</mybatis.version><mysql.version>8.0.33</mysql.version><spring-cloud.version>2025.0.0</spring-cloud.version><spring-cloud-alibaba.version>2025.0.0.0</spring-cloud-alibaba.version><spring-boot.version>3.5.0</spring-boot.version><common-core.version>1.0-SNAPSHOT</common-core.version></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><dependencyManagement><dependencies><!-- SpringCloud 微服务 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!-- SpringCloud 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><!-- SpringBoot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><!-- mybatis --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.version}</version></dependency><!-- MySQL驱动 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql.version}</version></dependency></dependencies></dependencyManagement></project>properties:Maven的全局变量定义区,用于集中管理项目中重复使用的配置值
<!-- 语法 --><spring-boot.version>3.2.4</spring-boot.version><!-- 引用方式 --><version>${spring-boot.version}</version>dependencyManagement:Maven依赖版本管理中心,只管理版本,不引入依赖
BOM导入(当前配置):BOM是一个特殊的POM文件,里面只干一件事——定义一堆依赖的版本号
| 标签 | 值 | 作用说明 |
|---|---|---|
| type | pom | 打包类型,表示依赖的不是JAR,是POM文件 |
| scope | import | 作用域,表示将依赖导入当前项目 |
pom + import表示将外部的一个POM文件导入当前项目
<!-- 示例 --><dependencyManagement><dependencies><!-- SpringCloud 微服务 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><!-- 版本:2025.0.0 --><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>Ctrl + 鼠标左键点击 groupId 或 artifactId 标签的内容,跳转到导入的POM文件
总之,上述示例中的配置的作用是:采用 Spring Cloud 官方 BOM 作为版本基准,将其内所有组件版本定义合并入当前项目的版本管理中心。此后引入具体 Spring Cloud 组件时无需再书写版本号,实现版本统一管控
dependencies:依赖引入区,这里写的每个依赖都会被下载、被 classpath 加载、被项目使用
3.2.2 modules
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="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><!-- Maven 的继承声明,让子模块继承父POM的所有配置 --><parent><groupId>org.example</groupId><artifactId>spring-cloud-blog</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>modules</artifactId><packaging>pom</packaging><modules><module>order-service</module><module>product-service</module></modules><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><dependency><groupId>org.example</groupId><artifactId>core</artifactId><version>${common-core.version}</version><scope>compile</scope></dependency></dependencies></project>3.3 构建数据
3.3.1 创建实体类
在core模块下创建订单和商品的实体类
@DatapublicclassOrderInfo{privateInteger id;privateInteger userId;privateInteger productId;privateInteger num;privateInteger price;privateInteger deleteFlag;privateDate createTime;privateDate updateTime;privateProductInfo productInfo;}@DatapublicclassProductInfo{privateInteger id;privateString productName;privateInteger productPrice;privateInteger status;privateDate createTime;privateDate updateTime;}3.3.2 初始化数据库
-- 订单服务createdatabaseifnotexists cloud_order charset utf8mb4;use cloud_order;-- 订单表droptableifexists order_detail;createtable order_detail (`id`intprimarykeyauto_incrementcomment'订单id',`user_id`bigint(20)notnullcomment'用户ID',`product_id`bigint(20)nullcomment'产品id',`num`INT(10)nulldefault0comment'下单数量',`price`bigint(20)notnullcomment'实付款',`delete_flag`tinyint(4)nulldefault0,`create_time`datetimedefaultnow(),`update_time`datetimedefaultnow());-- 数据初始化insertinto order_detail (user_id,product_id,num,price)values(2001,1001,1,99),(2002,1002,1,30),(2001,1003,1,40),(2003,1004,3,58),(2004,1005,7,85),(2005,1006,7,94);-- 产品服务createdatabaseifnotexists cloud_product charset utf8mb4;-- 产品表use cloud_product;droptableifexists product_detail;createtable product_detail (`id`intprimarykeyauto_incrementcomment'产品id',`product_name`varchar(128)nullcomment'产品名称',`product_price`bigint(20)notnullcomment'产品价格',`state`tinyint(4)nulldefault0comment'产品状态 0-有效 1-下架',`create_time`datetimedefaultnow(),`update_time`datetimedefaultnow());-- 数据初始化insertinto product_detail (id,product_name,product_price,state)values(1001,"T恤",101,0),(1002,"短袖",30,0),(1003,"短裤",44,0),(1004,"卫衣",58,0),(1005,"马甲",98,0),(1006,"羽绒服",101,0),(1007,"冲锋衣",30,0),(1008,"袜子",44,0),(1009,"鞋子",58,0),(10010,"毛衣",98,0);3.4 初始化配置文件
3.4.1 订单服务
application.yml
server:port:8000spring:application:name: order-service datasource:# 确保数据源存在url: jdbc:mysql://127.0.0.1:3306/cloud_order?characterEncoding=utf8&useSSL=falseusername: root password:123456driver-class-name: com.mysql.cj.jdbc.Driver mybatis:configuration:map-underscore-to-camel-case:true#自动驼峰转换3.4.2 商品服务
application.yml
server:port:9000spring:application:name: product-service datasource:# 确保数据源存在url: jdbc:mysql://127.0.0.1:3306/cloud_product?characterEncoding=utf8&useSSL=falseusername: root password:123456driver-class-name: com.mysql.cj.jdbc.Driver mybatis:configuration:map-underscore-to-camel-case:true#自动驼峰转换3.5 启动项目
order-service和product-service服务会继承父工程的所有依赖,创建启动类然后启动即可
@SpringBootApplicationpublicclassOrderServiceApplication{publicstaticvoidmain(String[] args){SpringApplication.run(OrderServiceApplication.class, args);}}@SpringBootApplicationpublicclassProductServiceApplication{publicstaticvoidmain(String[] args){SpringApplication.run(ProductServiceApplication.class, args);}}