【分布式微服务专题】从单体到分布式(一、SpringCloud项目初步升级)

目录

前言

从本节课开始,我将自己手写一个基于SpringCloud框架的web服务集群,中间会引入常用的微服务中间件。如:配置中心、网关、链路追踪、断路器等等。

本节课只是简单地从原有单体项目,然后升级成SpringCloud架构。

阅读对象

  1. 需要有实际Springboot-web开发经验

阅读导航

系列上一篇文章:《【分布式微服务专题】微服务架构演进

系列下一篇文章:《【分布式微服务专题】【微服务专题】从单体到分布式(一、SpringCloud整合Nacos)(整理中...)

前置知识

笔记正文

一、单体服务介绍

为了升级演示效果,我写了一个简单的SpringBoot单体应用,架构如下:

然后实现的功能也很简单,直接list获取库里面所有的数据。主要如下:

1)会员管理模块:提供一个/user/list接口,获取数据库里面所有用户数据

2)钱包管理模块:提供一个/wallet/list接口,获取数据库里面所有钱包数据

3)商品管理模块:提供一个/product/list接口,获取数据库里面所有商品数据

整体代码比较简单,就不贴了。我们前面有说过单体服务的缺点和限制,这边重申一下:

1)修改任意代码,甚至是application.yml都要重新打包编译部署,重启服务

2)单体机器存在性能瓶颈

3)很多时候,不同的服务QPS可能不一样,所以水平拓展的时候粒度不够精细

第三点对没有经验的小白可能理解上有点困难。简单说就是:在电商系统里面,正常来说访问商品模块的人,会比访问会员模块的人多。然后服务的性能瓶颈可能往往就是QPS最高的那个模块引起的,此时需要水平拓展服务,但由于是单体,所以每次拓展,都是对整个系统的拓展。但最理想的效果应该是,只对QPS最高的商品模块拓展

二、服务拆分

服务拆分之后,其实就可以理解为这就是所谓的【微服务】概念了。微服务简单说:一个 springboot 就是一个 微服务,并且这个 springboot 做的事情遵循单一职责。 比如说,在这里,服务经过拆分之后架构图成为了这样:(我新拓展了一个【订单服务】,虽然上面没贴,但是不妨碍理解)

甚至,经过水平拓展,也就是我们说的集群化之后,还可能是这样:

不过,随着服务的拆分,有一些衍生问题,却又无法避免。如下:

  1. 如何确定那些服务彼此之间的调用链路

比如上述架构图,可能存在会员服务调用订单服务的情况,那订单服务有两个服务,我怎么知道具体调用的是9081还是9082呢。甚至我的会员服务可能也有多台机器,那势必存在笛卡尔积的情况,他们之间的链路可能会更为复杂

  1. 同一组服务之间,甚至所有微服务之间,如何共享配置信息,配置如何自动刷新

比如说我多个微服务之间使用的是同一个数据库,redis,mq,这些配置信息理论上是可以共享的,而不必在每一个应用的application.yml文件上都声明

  1. 集群有新的服务上线,或者下线,如何处理

服务注册与发现

  1. 微服务如何不暴露细节,以一个整体去提供服务

网关

  1. 分布式事务
  2. 等等...(有一些我自己也不清楚,学习中)

三、分布式微服务升级前的思考

3.1 关于SpringBoot/SpringCloud的思考【有点门槛】

不知道你们是否跟我一样有同样的疑问,即:

  1. 什么是SpringBoot,如何新建一个SpringBoot项目
  2. 什么是SpringCloud,如何新建一个SpringCloud项目
  3. SpringCloudAlibaba和SpringCloud有什么关系

说来属实惭愧,我在此之前,真的没有很清晰的认知。只记得他们分别是Spring脚手架、微服务脚手架。但是我在做项目升级的时候发现,如果我的认知还是停留在这样片面的层次,会给我带来些不小的阻碍。

问题1:什么是SpringBoot,如何新建一个SpringBoot项目

不知道你们是否也一样,每次新建SpringBoot项目我都得重新百度一下如何新建,或者说,使用Idea的Spring Initializer来新建,不然对如何从空白项目新建一个SpringBoot没啥概念。经过这两天的学习之后,我终于是有点理解了。

简而言之,创建一个SpringBoot项目大概有如下三种方式:

  1. 新建一个继承自spring-boot-starter-parent的项目。如下:(这里分享一个相关知识点的传送门:《理解spring-boot-starter-parent》,大家伙学习下)

spring-boot-starter-parent主要是为我们使用、构建SpringBoot项目,提供了一些默认的配置。包括:

  1. 定义了Java编译版本为1.8。

  2. 使用UTF-8格式编码。

  3. 继承自spring-boot-dependencies,这个里边定义了Java+Spring开发常用依赖的版本,也正是因为继承了这个依赖,所以我们在写依赖时才不需要写版本号

  4. 预定义了一些Maven执行打包操作的配置

  5. 自动化的资源过滤。

  6. 自动化的插件配置。

  7. 针对application.properties和application.yml的资源过滤,包括通过profile定义的不同环境的配置文件,例如applicationdev.properties和application-dev.yml。

    使用spring-boot-starter-parent作为父项目,子项目可以继承父项目的依赖项、插件配置和默认设置,从而简化子项目的配置和管理。子项目可以通过在其pom.xml文件中引用父项目来继承这些配置,例如通过元素指定父项目的坐标。将相关的模块组织成多模块项目,可以提高代码的可维护性、复用性和团队协作效率。同时,使用父项目和子项目的结构,还可以方便地进行整体构建、测试和部署,保证模块之间的一致性和协调性。

  1. 新建一个项目,在<dependencyManagement>中添加spring-boot-dependencies的依赖

Spring Boot中的spring-boot-dependencies是一个特殊的依赖项,它提供了一组预定义的版本控制,用于管理Spring Boot及其相关库的版本。

在Spring Boot项目中,spring-boot-dependencies依赖是一个非常重要的依赖项,它主要作用是统一管理Spring Boot及其相关库的版本,避免版本冲突,简化依赖项管理。通过引入spring-boot-dependencies,你可以确保所使用的Spring Boot及其相关库的版本始终兼容,并能够轻松地升级到新的版本。

具体来说,spring-boot-dependencies包含了一个BOM(Bill of Materials)文件,这是一个包含了一系列库的清单,指定了这些库的版本号。当你在Maven或Gradle构建工具中添加spring-boot-dependencies依赖时,它会自动引入这个BOM文件。你可以直接声明其他Spring Boot相关的依赖项,并且这些依赖项会自动采用BOM中指定的版本。例如,你可以声明spring-boot-starter-web依赖,并且该依赖会自动使用BOM中定义的Spring Boot版本。

使用spring-boot-dependencies可以带来很多好处。首先,它可以统一管理所有的Spring Boot相关库的版本,避免不同库之间的版本冲突。其次,它可以简化依赖项的管理,不需要在每个项目中手动指定每个库的版本号。最后,它可以确保所使用的库的版本兼容性和一致性,避免因版本不同导致的问题。

总之,spring-boot-dependencies是Spring Boot框架提供的一个版本控制机制,它可以简化和统一项目中所使用的库的版本管理,确保版本的兼容性和一致性。

  1. 新建一个空白项目,在<dependency>中添加SpringBoot的依赖

其实就是没有使用上面1/2说的这两个做法咯。在这种情况下,需要我们自行去管理、确定依赖包的版本,容易出现兼容性问题。

通常,我们通过Spring Initializer或者Ali在线云原生构建也好,生成出来的SpringBoot都是采用方案1、2。

不知道大家有没有用心看我上面的介绍,我这边最后再结合自己的理解,简单的总结一下:

  1. 我们通常新建一个SpringBoot项目的时候,之所以在pom中继承自spring-boot-starter-parent主要是为了简化配置。这些简化配置包括:默认的JDK版本、默认的项目编码格式UTF-8、自动化的资源配置、插件配置。最重要的是,spring-boot-starter-parent继承自spring-boot-dependencies
  2. 而在spring-boot-dependencies中,定义了一系列Spring开发中,常用的jar包依赖,根据我的发现,在里面主要是包含了国外知名厂商的jar包,比如org.apache的东西
  3. 因为在spring-boot-dependencies里面预包含了很多jar包依赖,所以我们在实际使用中,很多jar包的引用不需要再显式地指定version。如下:

问题2:什么是SpringCloud,如何新建一个SpringCloud项目

我感觉在想通了问题1之后,对于这个问题我就没多少疑惑了。盲猜SpringCloud就是提供了很多关于微服务开发常用的中间件jar包依赖。根据我的理解也确实是这样

问题3:SpringCloudAlibaba和SpringCloud有什么关系

下面是我在【文心一言】看到的答案:

Spring Cloud Alibaba是Spring Cloud的子项目,符合Spring Cloud标准。它是一套完整的分布式解决方案,旨在推广阿里的产品。如果使用了Spring Cloud Alibaba,最好使用alibaba整个体系产品。

因此,Spring Cloud Alibaba和Spring Cloud的关系是,前者是后者的一部分,符合后者的标准。

但其实我不是很赞同这个说法,我觉得多少有点不准确。通过查看spring-cloud-dependenciesspring-cloud-alibaba-dependencies会发现,他们只是继承了同一个spring-cloud-dependencies-parent项目而已,所以文心一言说Spring Cloud Alibaba是Spring Cloud的子项目,符合Spring Cloud标准也没错。不过我个人认为:SpringCloud是SpringCloud公司给出的一个通用分布式微服务技术合集。而Spring Cloud Alibaba则是阿里给的一套,自己的解决方案,里面的微服务中间件都是阿里系的。说不定哪一天你就看到了Spring Cloud TencentSpring Cloud ByteDanceSpring Cloud HuaWei

我在后面将使用Spring Cloud Alibaba,大家可以通过传送门看看介绍:传送门。根据官方介绍,我们想要使用Spring Cloud Alibaba,只需要在pom中引入下面的依赖:

bash 复制代码
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${alibaba-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

附上一张,应该是Alibaba给出的分布式微服务生态图:

四、SpringCloud升级整合

4.1 新建父子项目

使用IDEA新建一个父子项目,具体过程我就不贴了,如果你理解了【三、分布式微服务升级前的思考】的内容,最后发现也没那么难。当然,有时候需要一点Maven相关知识,我这边建议直接花半个小时看看【菜鸟教程Maven系列】,个人认为比较需要了解的是:Maven构建生命周期、Maven POM

新建出来之后就是一个父子项目咯,然后每个项目有自己的@SpringBootApplication启动类。

但显然,这不是我们想要的结果,我们在【二、服务拆分】中提到的问题依然还没有解决。如:

  1. 服务注册与发现(微服务最重要的一个点)
  2. 分布式配置管理
  3. 服务限流降级
  4. 链路追踪
  5. 分布式事务
  6. 等等

所以,接下来才是真正的重头戏啊。后面我会逐步整合,下一篇则是整合Nacos配置中心到项目中。

学习总结

  1. 理解了SpringBoot跟SpringCloud项目的具体含义
  2. 对如何新建一个SpringBoot项目有个较为清晰的认知

感谢

感谢简书大佬【作者:】的文章《理解spring-boot-starter-parent

相关推荐
SamDeepThinking2 小时前
Java微服务练习方式
java·后端·微服务
米丘3 天前
微前端之 Web Components 完全指南
微服务·html
霸道流氓气质6 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
慧一居士6 天前
Feign的GET请求如何传递对象参数?
java·spring cloud
我登哥MVP6 天前
SpringCloud Alibaba 核心组件解析:服务链路追踪
java·spring boot·后端·spring·spring cloud·java-ee·maven
风吹夏回6 天前
RabbitMQ 核心术语 + Python pika 方法完整讲解
分布式·python·rabbitmq
慧一居士6 天前
SpringCloud 微服务Feigin 用的完整调用端和被调用的示例
java·spring cloud
风吹夏回6 天前
RabbitMQ 三种模式入门:HelloWorld、WorkQueue、PubSub
分布式·rabbitmq·ruby
霸道流氓气质6 天前
分布式追踪与 RequestId 传播完全指南
分布式
cheems95276 天前
[RabbitMQ高级特性] 消息确认机制:从 Ready / Unacked 到 basicAck、basicReject、basicNack 的底层拆解
分布式·rabbitmq·ruby