目录
今天学习的思维导图:
1.导入单体架构项目
1.1 安装mysql
资料提供好了MySQL的一个目录:
其中有MySQL的配置文件和初始化脚本:
复制到虚拟机的/root
目录。如果/root
下已经存在mysql
目录则删除旧的,如果不存在则直接复制本地的:
然后创建一个通用网络:
docker network create hm-net
使用下面的命令来安装MySQL:
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
-v /root/mysql/data:/var/lib/mysql \
-v /root/mysql/conf:/etc/mysql/conf.d \
-v /root/mysql/init:/docker-entrypoint-initdb.d \
--network hm-net\
mysql
创建以及运行mysql容器,此时因为存在挂载会执行配置文件,以及初始化的SQL文件。
查看容器状态:
docker ps
此时,如果我们使用MySQL的客户端工具连接MySQL,应该能发现已经创建了黑马商城所需要的表:
1.2 后端
然后是Java代码,在资料提供了一个hmall目录:
将其复制到你的工作空间,然后利用Idea打开。
项目结构如下:
按下ALT
+ 8
键打开services窗口,新增一个启动项:
找到Spring Boot,开启服务:
点击后应该会在services中出现hmall的启动项:
点击对应按钮,即可实现运行或DEBUG运行。
不过别着急!!
我们还需要对这个启动项做简单配置,在HMallApplication
上点击鼠标右键,会弹出窗口,然后选择Edit Configuration
:
在弹出窗口中配置SpringBoot的启动环境为local:
local:因为是在本地运行的项目,local配置了Linux的地址。
dev:在Linux运行,可以直接配置容器名,会被解析成对应的地址。
点击OK配置完成。接下来就可以运行了!
启动完成后,试试看访问下http:// http://localhost:8080/hi吧!
1.3 前端
在资料中还提供了一个hmall-nginx的目录:
其中就是一个nginx程序以及我们的前端代码,直接在windows下将其复制到一个非中文、不包含特殊字符的目录下。
# 启动nginx
start nginx.exe
# 停止
nginx.exe -s stop
# 重新加载配置
nginx.exe -s reload
# 重启
nginx.exe -s restart
特别注意:
nginx.exe 不要双击启动,而是打开cmd窗口,通过命令行启动。停止的时候也一样要是用命令停止。如果启动失败不要重复启动,而是查看logs目录中的error.log日志,查看是否是端口冲突。如果是端口冲突则自行修改端口解决。
启动成功后,访问http://localhost:18080,应该能看到我们的门户页面:
2.微服务
2.1 单体架构
单体架构(monolithic structure):顾名思义,整个项目中所有功能模块都在一个工程中开发;项目部署时需要对所有模块一起编译、打包;项目的架构设计、开发模式都非常简单。
优点:当项目规模较小时,这种模式上手快,部署、运维也都很方便,因此早期很多小型项目都采用这种模式。
但随着项目的业务规模越来越大,团队开发人员也不断增加,单体架构就呈现出越来越多的问题:
-
团队协作成本高:试想一下,你们团队数十个人同时协作开发同一个项目,由于所有模块都在一个项目中,不同模块的代码之间物理边界越来越模糊。最终要把功能合并到一个分支,你绝对会陷入到解决冲突的泥潭之中。
-
系统发布效率低:任何模块变更都需要发布整个系统,而系统发布过程中需要多个模块之间制约较多,需要对比各种文件,任何一处出现问题都会导致发布失败,往往一次发布需要数十分钟甚至数小时。
-
系统可用性差:单体架构各个功能模块是作为一个服务部署,相互之间会互相影响,一些热点功能会耗尽系统资源,导致其它服务低可用。
2.2 微服务
微服务架构,首先是服务化,就是将单体架构中的功能模块从单体应用中拆分出来,独立部署为多个服务。同时要满足下面的一些特点:
-
单一职责:一个微服务负责一部分业务功能,并且其核心数据不依赖于其它模块。
-
团队自治:每个微服务都有自己独立的开发、测试、发布、运维人员,团队人员规模不超过10人(2张披萨能喂饱)
-
服务自治:每个微服务都独立打包部署,访问自己独立的数据库。并且要做好服务隔离,避免对其它服务产生影响
当然,微服务架构虽然能解决单体架构的各种问题,但在拆分的过程中,还会面临很多其它问题。
比如:
-
如果出现跨服务的业务该如何处理?
-
页面请求到底该访问哪个服务?
-
如何实现各个服务之间的服务隔离?
2.3 SpringCloud
微服务拆分以后碰到的各种问题都有对应的解决方案和微服务组件,而SpringCloud框架是目前Java领域最全面的微服务组件的集合了。
而且SpringCloud依托于SpringBoot的自动装配能力,大大降低了其项目搭建、组件使用的成本。
版本之间需要对应:
在我们的父工程hmall中已经配置了SpringCloud以及SpringCloudAlibaba的依赖:
<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>
<dependencies>
<dependencyManagement>
对应的版本:
这样,我们在后续需要使用SpringCloud或者SpringCloudAlibaba组件时,就无需单独指定版本了。
3.微服务拆分
接下来,黑马商城这个单体项目拆分为微服务项目。
黑马商城项目的基本结构:
3.1 服务拆分原则
服务拆分一定要考虑几个问题:
-
什么时候拆?
-
如何拆?
3.1.1 什么时候拆
对于大多数小型项目来说,一般是先采用单体架构,随着用户规模扩大、业务复杂后再逐渐拆分为微服务架构。这样初期成本会比较低,可以快速试错。但是,这么做的问题就在于后期做服务拆分时,可能会遇到很多代码耦合带来的问题,拆分比较困难(前易后难)。
而对于一些大型项目,在立项之初目的就很明确,为了长远考虑,在架构设计时就直接选择微服务架构。虽然前期投入较多,但后期就少了拆分服务的烦恼(前难后易)。
3.1.2 怎么拆
微服务拆分时粒度要小,这其实是拆分的目标。具体可以从两个角度来分析:
-
高内聚:每个微服务的职责要尽量单一,包含的业务相互关联度高、完整度高。
-
低耦合:每个微服务的功能要相对独立,尽量减少对其它微服务的依赖,或者依赖接口的稳定性要强。
明确了拆分目标,接下来就是拆分方式了。做服务拆分时一般有两种方式:
-
纵向拆分:就是按照项目的功能模块来拆分。
-
横向拆分:看各个功能模块之间有没有公共的业务部分,如果有将其抽取出来作为通用服务。
3.2 拆分功能
一般微服务项目有两种不同的工程结构:
-
完全解耦:每一个微服务都创建为一个独立的工程,甚至可以使用不同的开发语言来开发,项目完全解耦。
-
优点:服务之间耦合度低
-
缺点:每个项目都有自己的独立仓库,管理起来比较麻烦
-
-
Maven聚合:整个项目为一个Project,然后每个微服务是其中的一个Module
-
优点:项目代码集中,管理和运维方便(授课也方便)
-
缺点:服务之间耦合,编译时间较长
-
3.2.1 商品服务
在hmall中创建module:
商品模块,我们起名为item-service
:
引入依赖:
<?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">
<parent>
<artifactId>hmall</artifactId>
<groupId>com.heima</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<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.heima</groupId>
<artifactId>hm-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</ar