Bootstrap

认识微服务

我们从单体架构的优缺点来分析,看看开发大型项目采用单体架构存在哪些问题,而微服务架构又是如何解决这些问题的。

单体架构

单体架构(monolithic structure):将业务的所有功能集中在一个项目中开发,打成一个包部署。之前的hmall项目,所有的业务功能都集中在hmall-service这个模块下,将来部署的时候只需要将其打成一个jar包即可部署,所以之前的项目是单体项目。

在这里插入图片描述

单体项目的架构简单,部署成本低。当项目规模较小时,这种模式上手快,部署、运维也都很方便,因此早期很多小型项目都采用这种模式。但随着项目的业务规模越来越大,团队开发人员也不断增加,单体架构就呈现出越来越多的问题:

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

在上述问题中,前两点相信大家在实战过程中应该深有体会。对于第三点系统可用性问题,很多同学可能感触不深。接下来我们就通过黑马商城这个项目,给大家做一个简单演示。

首先,我们修改hm-service模块下的com.hmall.controller.HelloController中的hello方法,模拟方法执行时的耗时:

在这里插入图片描述

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

  • http://192.168.202.128:8080/hi
  • http://192.168.202.128:8080/search/list?pageNo=1&pageSize=5

经过测试,目前/search/list 是比较正常的,访问耗时在200毫秒左右。

在这里插入图片描述

接下来,我们假设/hi,这个接口是一个并发较高的热点接口,我们通过Jemeter来模拟500个用户不停访问。下面资料中已经提供了Jemeter的测试脚本:

通过网盘分享的文件:jemeter
链接: https://pan.baidu.com/s/1phuOtb3RrLw67maj9-S0kg?pwd=9a8k 提取码: 9a8k
–来自百度网盘超级会员v5的分享

在这里插入图片描述

下载Jemeter,并配置环境变量:

jemeter依赖于jdk,需要有jdk才可以。Jemeter安装包在上面资料中已经存在,解压。

首先配置JEMETER_HOME

D:\develop\apache-jmeter-5.6.3

在这里插入图片描述

然后再配置CLASSPATH

ApacheJMeter_core.jar文件和jorphan.jar文件的路径配置到CLASSPATH里

%JEMETER_HOME%\lib\ext\ApacheJMeter_core.jar;%JEMETER_HOME%\lib\jorphan.jar

在这里插入图片描述

最后将bin目录添加到Path里

在这里插入图片描述

使用cmd命令,启动jmeter

在这里插入图片描述

导入JMeter并测试:

在这里插入图片描述

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

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

在这里插入图片描述

如果进一步提高/hi这个接口的并发,最终会发现/search/list接口的请求响应速度会越来越慢。这就是某一个接口并发太高,把Tomcat资源占完了,这样其他的进程访问的时候就很难进来了。

可见,单体架构的可用性是比较差的,功能之间相互影响比较大。此时如果我们对系统做水平扩展,增加更多机器,资源还是会被这样的热点接口占用,从而影响到其它接口,并不能从根本上解决问题。这也就是单体架构的扩展性差的一个原因。而要想解决这些问题,就需要使用微服务架构了。

微服务

微服务架构,首先是服务化,就是将单体架构中的功能模块拆分成多个独立的项目。同时要满足下面的一些特点:

  • 粒度小:每个功能模块拆分出去的要小一点,按照业务来拆分,拆出去的每个项目都要负责一块完整的功能,单一职责。
  • 团队自治:每个微服务项目都由单独的团队独立的开发和维护,团队人员规模不超过10人(2张披萨能喂饱)。
  • 服务自治:每个微服务都独立打包部署,访问自己独立的数据库。并且要做好服务隔离,避免对其它服务产生影响

例如,黑马商城项目,我们就可以把商品、用户、购物车、交易等模块拆分,交给不同的团队去开发,并独立部署:

在这里插入图片描述

那么,单体架构存在的问题有没有解决呢?

  • 团队协作成本高?
    • 由于服务拆分,每个服务代码量大大减少,参与开发的后台人员在1~3名,协作成本大大降低
  • 系统发布效率低?
    • 每个服务都是独立部署,当有某个服务有代码变更时,只需要打包部署该服务即可
  • 系统可用性差?
    • 每个服务独立部署,并且做好服务隔离,使用自己的服务器资源,不会影响到其它服务。

综上所述,微服务架构解决了单体架构存在的问题,特别适合大型互联网项目的开发,因此被各大互联网公司普遍采用。大家以前可能听说过分布式架构,分布式就是服务拆分的过程,其实微服务架构正是分布式架构的一种最佳实践的方案

当然,微服务架构虽然能解决单体架构的各种问题,但在拆分的过程中,还会面临很多其它问题。比如:

  • 如果出现跨服务的业务该如何处理?
  • 页面请求到底该访问哪个服务?
  • 如何实现各个服务之间的服务隔离?

这些问题,我们在后续的学习中会给大家逐一解答。

SpringCloud

微服务拆分以后碰到的各种问题都有对应的解决方案和微服务组件,而SpringCloud框架可以说是目前Java领域最全面的微服务组件的集合了。

在这里插入图片描述

而且SpringCloud依托于SpringBoot的自动装配能力,大大降低了其项目搭建、组件使用的成本。对于没有自研微服务组件能力的中小型企业,使用SpringCloud全家桶来实现微服务开发可以说是最合适的选择了!

https://spring.io/projects/spring-cloud#overview

目前SpringCloud最新版本为2022.0.x版本,对应的SpringBoot版本为3.x版本,但它们全部依赖于JDK17,目前在企业中使用相对较少。

SpringCloud版本SpringBoot版本
2022.0.x aka Kilburn3.0.x (jdk17)
2021.0.x aka Jubilee2.6.x, 2.7.x (Starting with 2021.0.3)
2020.0.x aka Ilford2.4.x, 2.5.x (Starting with 2020.0.3)
Hoxton2.2.x, 2.3.x (Starting with SR5)
Greenwich2.1.x
Finchley2.0.x
Edgware1.5.x
Dalston1.5.x

因此,我们推荐使用次新版本:Spring Cloud 2021.0.x以及Spring Boot 2.7.x版本。

另外,Alibaba的微服务产品SpringCloudAlibaba目前也成为了SpringCloud组件中的一员,我们课堂中也会使用其中的部分组件。

在我们的父工程hmall中已经配置了SpringCloud以及SpringCloudAlibaba的依赖:

在这里插入图片描述

对应的版本:

在这里插入图片描述

在这里插入图片描述

spring-cloud-dependencies的pom文件里面定义了各种各样的组件,也就是spring-cloud内部所有的组件在里面基本上都有对应的版本。因此,在引入spring cloud dependencies之后,在开发的过程中就不需要自己指定组件对应的版本,将来用到哪个组件直接将组件引入过来不需要单独指定版本号。

;