Git仓库(求star):https://github.com/Cyborg2077/xuecheng-plus

项目基础环境搭建: https://cyborg2077.github.io/2023/01/29/XuechengOnlinePart1/

内容管理模块(含实战内容):https://cyborg2077.github.io/2023/02/02/XuechengOnlinePart2/

媒资管理模块:https://cyborg2077.github.io/2023/02/10/XuechengOnlinePart3/

课程发布模块:https://cyborg2077.github.io/2023/02/28/XuechengOnlinePart4/

认证授权模块(含实战内容,解决微信登录):https://cyborg2077.github.io/2023/03/08/XuechengOnlinePart5/

选课学习模块:https://cyborg2077.github.io/2023/03/17/XuechengOnlinePart6/

项目优化:https://cyborg2077.github.io/2023/03/23/XuechengOnlinePart7/

ElasticSearch笔记,也是看的黑马的课:https://cyborg2077.github.io/2022/12/24/ElasticSearch/

Redis笔记,也是黑马的课:https://cyborg2077.github.io/2022/10/22/RedisPractice/

第1章 项目介绍&环境搭建v3.1

1.项目背景

1.1 在线教育市场环境

以下内容摘自https://report.iresearch.cn/content/2021/01/358854.shtml

在线教育行业是一个有着极强的广度和深度的行业,从校内到校外;从早幼教到职业培训;从教育工具到全信息化平台等等。

2020年的新冠疫情外生冲击,让在线教育再次站在聚光灯下。疫情下教育领域获融资最多,而其中在线教育最受资本青睐。据艾瑞咨询统计,2020年教育行业累计融资1164亿元,其中在线教育融资金额1034亿元,占比89%。与此同时,在行业处于困境的情况下,会加速洗牌,资源向好的企业集中。2020年资源向头部集中趋势明显,中小型机构生存更加困难。2020年资本向在线教育行业累计输送的1034亿元中,80%都流向了头部的5家公司。

To C市场

据艾瑞咨询统计核算,2020年中国在线教育行业市场规模2573亿元,过去4年的CAGR达34.5%,其中低幼及素质教育赛道、K12学科培训赛道在线化进程加快是在线教育市场快速增长的最主要贡献因素。疫情影响下,低幼及素质教育领域的在线化范围持续纵深,职业教育领域的在线化进程也在不断加速,新的供给和需求不断产生。但同时,2020年疫情外生冲击加快了2020年的在线教育进程,将会透支一部分2021年的增速,艾瑞预计2021年在线教育行业同比增速将回落到20%左右。

img

To B 市场

疫情也加速了整个教育产业链的进化,to B机构快速成长起来,扮演着赋能者的角色,课程内容、招生、师训、直播系统、管理系统等产品及服务大量涌现。随着云服务发展成熟以及疫情对直播课需求的催化,大量提供直播授课系统等PaaS/SaaS服务的机构迅速成长起来,成为各种会展上的主力军。

img

1.2 IT培训市场规模

中国IT人才供给报告(https://new.qq.com/rain/a/20210831A01JI600)

IT人才总体供不应求,高中低人才分别占比8%、41%、51%,详见下图:

img

IT服务是贯穿IT应用系统全生命周期的各项服务的统称,下图是IT服务产品图谱,本项目属于IT培训产业。

img

下图是IT培训市场规模:

img

1.3 学成在线项目背景

软件总体分为两类:系统软件和应用软件,应用软件包括:运营类、管理类、工具类等,运营类的项目由运营商按照企业的商业模式去运营,比如:外卖项目、滴滴打车、在线教育等;管理类的项目是为某个组织完成某业务的数据及业务管理,比如:医院MIS(管理信息系统--Management Information System)系统,ERP系统(ERP全称是Enterprise Resource Planning,其中文名字为企业资源计划,这个系统是针对物资资源管理,人力资源管理,财务资源管理,信息资源管理集成一体化的一个企业管理系统。)等;工具类的项目是为了某个领域完成具体的需求,比如:数据采集系统、文件处理系统等。

学成在线项目属于运营类的项目,运营类项目的研发可能是自研也可能是外包,自研是由运营商成立软件研发部门自己进行软件研发,运营商即是甲方也是乙方,外包则是由运营商外包给第三方软件公司进行研发,运营商是甲方,软件公司是乙方。

学成在线项目是本公司自研的一个专门针对成人职业技能教育的网络课堂系统,网站提供了成人职业技能培训的相关课程,如:软件开发培训、职业资格证书培训、成人学历教育培训等课程。项目基于B2B2C的业务模式,培训机构可以在平台入驻、发布课程,运营人员对发布的课程进行审核,审核通过后课程才可以发布成功,课程包括免费和收费两种形式,对于免费课程可以直接选课学习,对于收费课程在选课后需要支付成功才可以继续学习。

什么是B2B2C?

B2B2C是一种电子商务类型的网络购物商业模式,B是Business的简称,C是Consumer的简称,第一个B指的是商品或服务的供应商,第二个B指的是从事电子商务的企业,C则是表示消费者。

B2B的定义:企业跟企业之间的电子商务运作方式。

B2C的定义:企业跟消费者之间的电子商务运作方式。

2.项目介绍

下边分别从业务和技术两个方式介绍项目。

2.1 项目业务介绍

本项目包括了用户端、机构端、运营端。

核心模块包括:内容管理、媒资管理、课程搜索、订单支付、选课管理、认证授权等。

下图是项目的功能模块图:

img

下边介绍业务流程:

1、课程编辑与发布流程如下:

img

2、课程发布后学生登录平台进行选课、在线学习。

免费课程可直接学习,收费课程需要下单购买。

学生选课流程如下:

img

2.3 项目技术架构

本项目采用前后端分离架构,后端采用SpringBoot、SpringCloud技术栈开发,数据库使用了MySQL,还使用的Redis、消息队列、分布式文件系统、Elasticsearch等中间件系统。

划分的微服务包括:内容管理服务、媒资管理服务、搜索服务、订单支付服务、 学习中心服务、系统管理服务、认证授权服务、网关服务、注册中心服务、配置中心服务等。

下图是项目的技术架构图:

img

各层职责说明如下:

名称功能描述
用户层用户层描述了本系统所支持的用户类型包括:pc用户、app用户、h5用户。pc用户通过浏览器访问系统、app用户通过android、ios手机访问系统,H5用户通过h5页面访问系统。
CDNCDN全称Content Delivery Network,即内容分发网络,本系统所有静态资源全部通过CDN加速来提高访问速度。系统静态资源包括:html页面、js文件、css文件、image图片、pdf和ppt及doc教学文档、video视频等。
负载均衡系统的CDN层、UI层、服务层及数据层均设置了负载均衡服务,上图仅在UI层前边标注了负载均衡。 每一层的负载均衡会根据系统的需求来确定负载均衡器的类型,系统支持4层负载均衡+7层负载均衡结合的方式,4层负载均衡是指在网络传输层进行流程转发,根据IP和端口进行转发,7层负载均衡完成HTTP协议负载均衡及反向代理的功能,根据url进行请求转发。
UI层UI层描述了系统向pc用户、app用户、h5用户提供的产品界面。根据系统功能模块特点确定了UI层包括如下产品界面类型: 1)面向pc用户的门户系统、学习中心系统、教学管理系统、系统管理中心。 2)面向h5用户的门户系统、学习中心系统。 3)面向app用户的门户系统、学习中心系统。
微服务层微服务层将系统服务分类三类:业务服务、基础服务、第三方代理服务。 业务服务:主要为学成在线核心业务提供服务,并与数据层进行交互获得数据。 基础服务:主要管理学成在线系统运行所需的配置、日志、任务调度、短信等系统级别的服务。 第三方代理服务:系统接入第三方服务完成业务的对接,例如认证、支付、视频点播/直播、用户认证和授权。
数据层数据层描述了系统的数据存储的内容类型,关系性数据库:持久化的业务数据使用MySQL。 消息队列:存储系统服务间通信的消息,本身提供消息存取服务,与微服务层的系统服务连接。 索引库:存储课程信息的索引信息,本身提供索引维护及搜索的服务,与微服务层的系统服务连接。 缓存:作为系统的缓存服务,作为微服务的缓存数据便于查询。 文件存储:提供系统静态资源文件的分布式存储服务,文件存储服务器作为CDN服务器的数据来源,CDN上的静态资源将最终在文件存储服务器上保存多份。

2.2 项目演示

下边在测试环境演示系统的核心业务流程,本项目主要包括三类用户角色:学生、教学机构的老师、平台运营人员,核心业务流程包括课程发布流程、选课学习流程。

课程发布流程:

1、教学机构的老师登录教学管理平台,编辑课程信息,发布自己的课程。

2、平台运营人员登录运营平台审核课程、视频等信息,审核通过后课程方可发布。

流程图如下:

img

课程发布后学生登录平台进行选课、在线学习。

免费课程可直接学习,收费课程需要下单购买。

学生选课学习流程如下:

img

2.4 面试

1、详细说说你的项目吧

从以下几个方面进行项目介绍:

1、项目的背景,包括:是自研还是外包、什么业务、服务的客户群是谁、谁去运营等问题。

2、项目的业务流程

3、项目的功能模块

4、项目的技术架构

5、个人工作职责

6、个人负责模块的详细说明,包括模块的设计,所用到的技术,技术的实现方案等。

一个例子:

我最近参与的项目是我们公司自研的专门针对成人职业技能教育的网络课堂系统,网站提供了成人职业技能培训的相关课程,如:软件开发培训、职业资格证书培训、成人学历教育培训等课程。项目基于B2B2C的业务模式,培训机构可以在平台入驻、发布课程,我们公司作为运营方由专门的人员对发布的课程进行审核,审核通过后课程才可以发布成功,课程包括免费和收费两种形式,对于免费课程普通用户可以直接选课学习,对于收费课程在选课后需要支付成功才可以继续学习。

本项目包括用户端、机构端、运营端三个端。

核心模块包括:内容管理、媒资管理、课程搜索、订单支付、选课管理、认证授权等。

本项目采用前后端分离架构,后端采用SpringBoot、SpringCloud技术栈开发,数据库使用了MySQL,还使用的Redis、消息队列、分布式文件系统、Elasticsearch等中间件系统。

划分的微服务包括:内容管理服务、媒资管理服务、搜索服务、订单支付服务、 学习中心服务、系统管理服务、认证授权服务、网关服务、注册中心服务、配置中心服务等。

我在这个项目中负责了内容管理、媒资管理、订单支付模块的设计与开发。

内容管理模块,是对平台上的课程进行管理,课程的相关信息比较多这里在数据库设计了课程基本信息表、课程营销表、课程计划、课程师资表进行存储 ,培训机构要发布一门课程需要填写课程基本信息、课程营销信息、课程计划信息、课程师资信息,填写完毕后需要提交审核,由运营人员进行课程信息的审核,整个审核过程是程序自动审核加人工确认的方式,通常24小时审核完成。课程审核通过即可发布课程,课程的相关信息会聚合到课程发布表中,这里不仅要将课程信息写到课程发布表还要将课程信息写到索引库、分布式文件系统中,所以这里存在分布式事务的问题,项目使用本地消息表加任务调度的方式去解决这里的分布式事务,保存数据的最终一致性。


  • 流程说明
    1. 用户可以通过pc、手机等客户端访问系统进行在线学习。
    2. 系统应用CDN技术,对一些图片、CSS、视频等资源从CDN调度访问。
    3. 所有的请求全部经过负载均衡器。
    4. 对于PC、H5等客户端请求,首先请求UI层,渲染用户界面。
    5. 客户端UI请求服务层获取进行具体的业务操作。
    6. 服务层将数据持久化到数据库。

项目技术栈

  • 学成在线按照技术分层的基础上,需要对主要层次使用具体的技术作说明。下面是学成在线技术栈结构图。 img

3,项目开发环境搭建

3.1项目工程搭建

3.1.1工程结构关系

  • 学成在线使用 Maven 来进行项目的管理和构建。整个项目分为三大类工程:父工程、基础工程 和微服务工程

img

每一种类的工程都有不同的作用,下面是对其功能进行说明:

  • 父工程
    • 对依赖包的版本进行管理
    • 本身为Pom工程,对子工程进行聚合管理
  • 基础工程
    • 继承父类工程
    • 提供基础类库
    • 提供工具类库
  • 微服务工程
    • 分别从业务、技术方面划分模块,每个模块构建为一个微服务。
    • 每个微服务工程依赖基础工程,间接继承父工程。
    • 包括:内容管理服务、媒资管理服务、搜索服务、缓存服务、消息服务等。

3.2构架父工程

父工程的职责是对依赖包的版本进行管理

  1. 创建父工程,新建模块,选择Spring Initalizr,填写模块信息
    • 模块名:xuecheng-plus-parent
    • 包名:com.xuecheng
  2. 依赖管理定义
    • 父工程中没有代码,不用去依赖其他的包,它的作用就是限定其他子工程依赖包的版本号,即在dependencyManagement中去编辑即可
    • 确定父工程为一个pom工程,在pom.xml中添加如下内容

确定项目所依赖的包及其版本号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
<org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
<spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version>
<org.projectlombok.version>1.18.8</org.projectlombok.version>
<javax.servlet-api.version>4.0.1</javax.servlet-api.version>
<fastjson.version>1.2.83</fastjson.version>
<druid-spring-boot-starter.version>1.2.8</druid-spring-boot-starter.version>
<mysql-connector-java.version>8.0.30</mysql-connector-java.version>
<mybatis-plus-boot-starter.version>3.4.1</mybatis-plus-boot-starter.version>
<commons-lang.version>2.6</commons-lang.version>
<minio.version>8.4.3</minio.version>
<xxl-job-core.version>2.3.1</xxl-job-core.version>
<swagger-annotations.version>1.5.20</swagger-annotations.version>
<commons-lang3.version>3.10</commons-lang3.version>
<okhttp.version>4.8.1</okhttp.version>
<swagger-spring-boot-starter.version>1.9.0.RELEASE</swagger-spring-boot-starter.version>
<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>

编写dependencyManagement l来限定所依赖包的版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
<!-- lombok,简化类的构建-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</dependency>
<!-- mapstruct 代码生成器,简化java bean之间的映射 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations.version}</version>
</dependency>
<!-- Servlet 容器管理 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- fastjson ,json解析工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- druid 连接池管理 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid-spring-boot-starter.version}</version>
</dependency>
<!-- mySQL数据库驱动包管理 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>
<!-- mybatis plus 集成Spring Boot启动器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus-boot-starter.version}</version>
</dependency>
<!-- mybatis plus 代码生成器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis-plus-boot-starter.version}</version>
</dependency>
<!-- 工具类管理 -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
</dependency>
<!-- 分布式文件系统 minIO的客户端API包 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio.version}</version>
</dependency>
<!--google推荐的一套工具类库-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>25.0-jre</version>
</dependency>
<!--分布式任务调度-->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${xxl-job-core.version}</version>
</dependency>
<!--Spring boot单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>${swagger-spring-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

编辑打包插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<build>
<finalName>${project.name}</finalName>
<!--编译打包过虑配置-->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<!--打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!--指定项目源码jdk的版本-->
<source>1.8</source>
<!--指定项目编译后的jdk的版本-->
<target>1.8</target>
<!--配置注解预编译-->
<annotationProcessorPaths>
<!-- <path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>-->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<!--责处理项目资源文件并拷贝到输出目录,如果有额外的资源文件目录则需要配置-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<encoding>utf-8</encoding>
<!--使用默认分隔符,resource中可以使用分割符定义过虑的路径-->
<useDefaultDelimiters>true</useDefaultDelimiters>
</configuration>
</plugin>
</plugins>
</build>

3.3构建基础工程

基础工程的职责是提供一些系统架构所需要的基础类库以及一些工具类库

  1. 创建基础工程

    • 模块名:xuecheng-plus-base
    • 包名:com.xuecheng
  2. 编辑pom.xml

    • 注意base的父工程是parent(需要设置base包下pom文件的parent属性)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <parent>
      <groupId>com.xuecheng</groupId>
      <artifactId>xuecheng-plus-parent</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <!--基于当前pom.xml找到父工程-->
      <relativePath>../xuecheng-plus-parent</relativePath>
      </parent>
      <artifactId>xuecheng-plus-base</artifactId>
      <properties>
      <java.version>1.8</java.version>
      </properties>
      <dependencies>
      <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      </dependency>
      <!-- fast Json -->
      <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      </dependency>
      <!-- servlet Api 依赖 -->
      <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <scope>provided</scope>
      </dependency>
      <!-- 通用组件 -->
      <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      </dependency>
      <dependency>
      <groupId>commons-codec</groupId>
      <artifactId>commons-codec</artifactId>
      <version>1.11</version>
      </dependency>
      <dependency>
      <groupId>io.swagger</groupId>
      <artifactId>swagger-annotations</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-log4j2</artifactId>
      </dependency>
      <!--根据扩展名取mimetype-->
      <dependency>
      <groupId>com.j256.simplemagic</groupId>
      <artifactId>simplemagic</artifactId>
      <version>1.17</version>
      </dependency>
      <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      </dependency>
      <dependency>
      <groupId>com.google.zxing</groupId>
      <artifactId>core</artifactId>
      <version>3.3.3</version>
      </dependency>
      <dependency>
      <groupId>com.google.zxing</groupId>
      <artifactId>javase</artifactId>
      <version>3.3.3</version>
      </dependency>
      <dependency>
      <groupId>com.fasterxml.jackson.module</groupId>
      <artifactId>jackson-module-parameter-names</artifactId>
      </dependency>
      <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-jdk8</artifactId>
      </dependency>
      <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-jsr310</artifactId>
      </dependency>
      </dependencies>

      <build>
      <plugins>
      <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      </plugins>
      </build>

      </project>

3.4添加.gitignore文件

  • 在项目工程的根目录(xuecheng-plus)新增.gitignore文件,设置不需要提交的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
logs/
### VS Code ###
.vscode/

3.5 项目数据库环境

  • MySQL版本要使用8.0以上,然后创建一个xc_content数据库

    1
    CREATE DATABASE xc_content
  • 之后导入课程提供好的建表sql语句即可

3.6 虚拟机开发环境

https://www.bilibili.com/read/cv23342314?spm_id_from=333.999.0.0&jump_opus=1

p6关于开发环境,如果你没有用到老师的虚拟机而是在自己虚拟机或者服务器重新安装以下为具体安装步骤,软件版本与老师一致(minio容器除外)。

1.安装Docker 18.09.0的详细步骤

步骤1:安装依赖库


sudo yum install -y yum-utils device-mapper-persistent-data lvm2


步骤2:添加Docker源


sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

推荐下面的阿里云加速镜像

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo


步骤3:安装Docker


sudo yum install docker-ce-18.09.0 docker-ce-cli-18.09.0 containerd.io


步骤4:启动Docker


sudo systemctl start docker


步骤5:设置Docker开机自启


sudo systemctl enable docker


2.在Docker中安装MySQL 8

步骤1:拉取MySQL 8的镜像文件


docker pull mysql:8


步骤2:使用Docker创建MySQL容器,创建MySQL数据存储目录并挂载到容器中


mkdir -p /data/mysql


docker run -p 3306:3306 --name mysql -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:8


说明:

参数-p 3306:3306表示将Docker容器的3306端口映射到宿主机的3306端口。参数--name mysql表示给容器起个名字叫mysql,方便管理。

参数-v /data/mysql:/var/lib/mysql表示将宿主机的/data/mysql目录挂载到容器的/var/lib/mysql目录上,这样可以实现数据持久化。

参数-e MYSQL_ROOT_PASSWORD=root表示设置MySQL的root用户的密码为root。

步骤3:进入MySQL容器执行相关操作


docker exec -it mysql bash

说明:进入容器后可以在容器内使用MySQL客户端来操作MySQL数据库。


mysql -u root -p回车


输入你的密码(我的密码是:root)


exit

说明:退出mysql窗口


exit

说明:退出mysql容器


3.在Docker中安装Nacos 1.4.1

步骤1:拉取Nacos 1.4.1的镜像文件


docker pull nacos/nacos-server:1.4.1


步骤2:使用Docker创建Nacos容器,在宿主机上创建Nacos数据存储目录并挂载到容器中


mkdir /data/nacos


docker run -p 8848:8848 --name nacos -v /data/nacos:/home/nacos/nacos-server-1.4.1/nacos-logs -d nacos/nacos-server:1.4.1


说明:

参数-p 8848:8848表示将Docker容器的8848端口映射到宿主机的8848端口。

参数--name nacos表示给容器起个名字叫nacos,方便管理。

参数-v /data/nacos:/home/nacos/nacos-server-1.4.1/nacos-logs表示将宿主机的/data/nacos目录挂载到容器的/home/nacos/nacos-server-1.4.1/nacos-logs目录上,这样可以实现数据持久化。

步骤3:设置Nacos开机自启


docker update --restart=always nacos


4.在Docker中安装RabbitMQ 3.8.34

步骤1:拉取RabbitMQ 3.8.34的镜像文件


docker pull rabbitmq:3.8.34-management


步骤2:使用Docker创建RabbitMQ容器


mkdir /data/rabbitmq


docker run -p 15672:15672 -p 5672:5672 --name rabbitmq -v /data/rabbitmq:/var/lib/rabbitmq -d rabbitmq:3.8.34-management


说明:

参数-p 15672:15672 -p 5672:5672表示将Docker容器的15672和5672端口映射到宿主机的15672和5672端口。

参数--name rabbitmq表示给容器起个名字叫rabbitmq,方便管理。

参数-v /data/rabbitmq:/var/lib/rabbitmq表示将宿主机的/data/rabbitmq目录挂载到容器的/var/lib/rabbitmq目录上,这样可以实现数据持久化。

说明:

步骤3:设置RabbitMQ开机自启


docker update --restart=always rabbitmq


5.在Docker中安装Redis 6.2.7

步骤1:拉取Redis 6.2.7的镜像文件


docker pull redis:6.2.7


步骤2:使用Docker创建Redis容器;在宿主机上创建Redis数据存储目录并挂载到容器中


mkdir /data/redis


docker run -p 6379:6379 --name redis -v /data/redis:/data -d redis:6.2.7 redis-server --appendonly yes


说明:

参数-p 6379:6379表示将Docker容器的6379端口映射到宿主机的6379端口。

参数--name redis表示给容器起个名字叫redis,方便管理。

参数-v /data/redis:/data表示将宿主机的/data/redis目录挂载到容器的/data目录上,这样可以实现数据持久化。

参数redis-server --appendonly yes表示开启Redis的数据持久化功能。

步骤3:设置Redis开机自启


docker update --restart=always redis


6.在Docker中安装XXL-Job-Admin 2.3.1

步骤1:拉取XXL-Job-Admin 2.3.1的镜像文件


docker pull xuxueli/xxl-job-admin:2.3.1


步骤2:使用Docker创建XXL-Job-Admin容器;在宿主机上创建XXL-Job-Admin数据存储目录并挂载到容器中


mkdir /data/xxl-job-admin


docker run -p 8080:8080 --name xxl-job-admin -v /data/xxl-job-admin:/data/applogs -d xuxueli/xxl-job-admin:2.3.1


说明:

参数-p 8080:8080表示将Docker容器的8080端口映射到宿主机的8080端口。

参数--name xxl-job-admin表示给容器起个名字叫xxl-job-admin,方便管理。

参数-v /data/xxl-job-admin:/data/applogs表示将宿主机的/data/xxl-job-admin目录挂载到容器的/data/applogs目录上,这样可以实现日志持久化。

步骤3:设置XXL-Job-Admin开机自启


docker update --restart=always xxl-job-admin


7.在Docker中安装Minio RELEASE.2022-09-07

步骤1:拉取Minio RELEASE.2022-09-07的镜像文件


docker pull minio/minio


步骤2:使用Docker创建Minio容器;在宿主机上创建Minio数据存储目录并挂载到容器中


mkdir /data/minio

docker run -p 9000:9000 --name minio -v /data/minio:/data -d minio/minio server /data


说明:参数-p 9000:9000表示将Docker容器的9000端口映射到宿主机的9000端口。参数--name minio表示给容器起个名字叫minio,方便管理。参数server /data表示在/data目录下启动Minio服务。参数-v /data/minio:/data表示将宿主机的/data/minio目录挂载到容器的/data目录上,这样可以实现数据持久化。

步骤3:设置Minio开机自启


docker update --restart=always minio


8.在Docker中安装Elasticsearch 7.12.1

步骤1:拉取Elasticsearch 7.12.1的镜像文件


docker pull elasticsearch:7.12.1


步骤2:使用Docker创建Elasticsearch容器;在宿主机上创建Elasticsearch数据存储目录并挂载到容器中


mkdir /data/elasticsearch


docker run -p 9200:9200 -p 9300:9300 --name elasticsearch -v /data/elasticsearch:/usr/share/elasticsearch/data -e "discovery.type=single-node" -d elasticsearch:7.12.1


说明:

参数-p 9200:9200 -p 9300:9300表示将Docker容器的9200和9300端口映射到宿主机的9200和9300端口。

参数--name elasticsearch表示给容器起个名字叫elasticsearch,方便管理。

参数-e "discovery.type=single-node"表示设置Elasticsearch为单节点模式。

参数-v /data/elasticsearch:/usr/share/elasticsearch/data表示将宿主机的/data/elasticsearch目录挂载到容器的/usr/share/elasticsearch/data目录上,这样可以实现数据持久化。

步骤4:设置Elasticsearch开机自启


docker update --restart=always elasticsearch


9.在Docker中安装Kibana 7.12.1

步骤1:拉取Kibana 7.12.1的镜像文件


docker pull kibana:7.12.1


步骤2:使用Docker创建Kibana容器


docker run -p 5601:5601 --name kibana -d kibana:7.12.1


说明:参数-p 5601:5601表示将Docker容器的5601端口映射到宿主机的5601端口。参数--name kibana表示给容器起个名字叫kibana,方便管理。

步骤3:设置Kibana开机自启


docker update --restart=always kibana


10.在Docker中安装nginx 1.12.2的步骤如下:

步骤1. 拉取nginx:1.12.2的镜像文件;创建一个数据存储目录,比如/data/nginx

docker pull nginx:1.12.2


mkdir /data/nginx/conf


mkdir /data/nginx/logs


mkdir /data/nginx/html


步骤2. 启动一个nginx 1.12.2的容器并将数据存储目录挂载到容器内部的/data目录中

docker run -d --name nginx -p 80:80 -v /data/nginx/html:/usr/share/nginx/html -v /data/nginx/conf:/etc/nginx -v /data/nginx/logs:/var/log/nginx -d nginx:1.12.2

步骤3. 设置应用开机自启


docker update --restart=always nginx


以上步骤完成后,就可以启动nginx容器并访问ip:80了。

nginx挂载目录这里有同学可能会有疑问,平时我们打包的vue文件都生成在dist中,为什么没有挂载/data/nginx/dist目录呢?

因为data/nginx/dist 目录和 /data/nginx/html 目录的作用是一样的,用于存放Nginx服务提供的静态文件。

所以你可以选择任意一个目录挂载到 Docker 容器中,而无需挂载两个目录同时使用。

在步骤1语句4仅仅挂载了 /data/nginx/html 目录,这是因为在 Nginx 默认配置中,静态文件的根目录是 /usr/share/nginx/html,

所以我们需要挂载主机中的 /data/nginx/html 目录到容器中的 /usr/share/nginx/html 目录。

如果更喜欢使用 /data/nginx/dist 目录,则可以将上面命令中的 /data/nginx/html 目录改为 /data/nginx/dist 目录,

虚拟机错误

虚拟机开机network服务failed并且无ip

重启网卡报错Job for network.service failed becausethecontrolprocessexitedwitnerrorcodesustemcts+atus network.service"andjournalctlXefor details.

https://blog.csdn.net/m0_49562857/article/details/128137519

执行下面命令

1
2
nmcli networking on
systemctl restart network ##重启网卡