第三章
优学题库项目基本框架搭建
优就业.JAVA教研室
学习目标
- 了解优学题库项目介绍
- 理解项目搭建
- 理解搭建管理后台
- 理解逆向生成代码
- 掌握模块工程配置
- 掌握搭建Nacos注册中心
- 掌握注册各个微服务到Nacos
- 掌握搭建网关服务
1. 优学在线考试题库系统介绍
1.1 项目介绍
中公教育集团作为一家上市培训企业,每天服务于几千万学员,涉及题库类型丰富多样,具有海量的题目信息。
优学题库项目正是基于这样的背景下诞生的一套题库系统,系统支持自定义题库类型,可以满足广大学员对于各类型题型的学习使用。优学题库系统采用SpringCloud Alibaba分布式架构体系,基于VUE前后端分离技术实现后台管理,基于微信小程序实现移动端应用。
1.2 系统界面
1、用户移动端
2、系统管理端
2. 搭建项目
功能架构
技术架构图
2.1 项目结构说明
核心是microservice这块儿,它分两类微服务:
-
后台CRUD微服务
-
content:内容管理系统(product) 10001
-
member:会员管理系统(user)10002
-
question:题库管理系统(warehouse) 10003
-
后端采用:Springboot+SpringCloud GateWay+Mybatis plus+Nacos
前端采用:Vue+Element ui+Node.js
数据层:mysql、redis、rabbitmq、阿里OSS
后台管理前端:uxue-admin(1000)
网关:uxue-gateway(8888)
2.2 数据准备
把课前资料中的数据文件导入数据库:
导入数据库之后:
uxue_admin:管理后台数据库
uxue_cms:广告内容服务数据库
uxue_qms:题目服务数据库
uxue_ums:会员服务数据库
注意数据库版本:5.7
2.3. git安装和配置
2.3.1 什么是Git
Git是一款免费、开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
2.3.2 Git相关软件下载
Git的下载页面: https://git-scm.com/ 目前最新版:Git-2.13.0 注意下载对应操作系统位数的安装包。
2.3.3 Git安装与配置
1、选中GIT安装包,Git-2.13.0-64-bit.exe 单击右键,弹出对话框,点击【解除锁定】。
2、双击GIT安装包,Git-2.13.0-64-bit.exe 开始安装(如有安全告警,点击运行)
3、出现授权信息页面,点击下一步即可
4、接下来逐步点击【Next】即可安装成功
2.3.4 git成功
在命令行输入命令
git --version
屏幕显示:git version 2.13.0.windows.1
出现上面的版本号提示表示git安装成功。
2.3.5 Git配置
配置当前开发者名称、邮箱、默认推送方式
git config --global user.name "offcn-java"
git config --global user.email "myqq@qq.com"
git config --global push.default simple
注意–global 参数 表示全局配置。
查看配置是否生效:
git config -l
查看配置是否正确
2.3. 使用gitee创建仓库
2.3.1 申请gitee账号
访问地址:https://gitee.com/signup 注册账号
2.3.2.登录gitee创建仓库
2.3.3 克隆项目到本地:
找到项目克隆地址:
在命令执行命令克隆项目到本地:
git clone https://gitee.com/hk109/uxue.git
2.4. 项目初始创建
把资料/基础工程中的文件
copy到 clone下来的uxue工程中
接下来在idea中导入uxue工程:
点击“OK”,一路下一步:项目成功导入到Idea
2.4.1 在idea的Terminal窗口,查看git状态:
git status
2.4.2 把当前项目新增文件添加到待处理列表
git add .
2.4.3 提交当前项目到git本地仓库
git commit -m "优学题库系统"
2.4.4 推送到远程仓库:
git push origin master
效果:
2.5. 创建项目模块
2.5.1. 创建广告内容服务模块
创建完成:
项目统一定义springCloud和spring cloud alibaba版本及初始化依赖:
<properties>
<java.version>1.8</java.version>
<spring-cloud-alibaba.version>2.2.0.RELEASE</spring-cloud-alibaba.version>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<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>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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.5.2. 创建会员服务模块
新建模块:
其他项,参考广告内容服务模块。
2.5.3. 创建题目服务模块
其他项参考广告内容服务模块
2.5.4. 完整工程
设置uxue父工程管理相关子模块,修改pom.xml
<modules>
<module>u-context</module>
<module>u-member</module>
<module>u-question</module>
</modules>
修改后刷新maven
接下来把这些新模块push到gitee。
git add .
git commit -m "创建后台工程"
git push origin master
3、搭建管理后台
管理后台使用人人开源的后台管理框架,完成快速搭建。
3.1、下载人人开源后台管理框架
renren-fast 管理后台后端(服务端) https://gitee.com/renrenio/renren-fast.git
renren-fast-vue 管理后台前端(VUE前端界面) https://gitee.com/renrenio/renren-fast-vue.git
3.2、添加人人开源管理后端代码到java项目
拷贝文件夹renren-fast到uxue根目录
POM文件 添加模块管理
<module>renren-fast</module>
刷新项目maven
3.3、修改renren-fast 服务的配置文件
文件路径:src/main/resources/application-dev.yml
修改数据库连接为自己的mysql数据库连接
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/uxue_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: root
initial-size: 10
max-active: 100
min-idle: 10
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
#Oracle需要打开注释
#validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
stat-view-servlet:
enabled: true
url-pattern: /druid/*
#login-username: admin
#login-password: admin
filter:
stat:
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: false
wall:
config:
multi-statement-allow: true
3.4、启动renren-fast服务
运行renren-fast后台
启动运行成功:
3.5、测试服务运行状态
浏览器输入:http://localhost:8080/renren-fast/
显示结果:
结果如上所示,则表示服务运行正常。另外结果里面的invalid token说明权限不足,不是指服务不正常。
4. 逆向工程生成代码
4.1、下载代码生成器框架
git clone https://gitee.com/renrenio/renren-generator.git
4.2、导入生成器代码到uxue项目
拷贝文件夹renren-fast到uxue项目根目录
POM文件 添加依赖
<module>renren-generator</module>
最终uxue项目结构:
4.3、逆向生成管理前后端代码
下面以生成context广告内容服务的代码为例,其他模块操作类似!!!!!!!
4.3.1. 修改配置
(1)、修改application.yml,把数据库及其连接信息改成广告的数据库:uxue_cms
(2)、修改generator.properties:
(3)、修改controller模板文件
src/main/resources/template/Controller.java.vm
暂时删除引入的包,后面再引入
//import org.apache.shiro.authz.annotation.RequiresPermissions;
注释RequiresPermissions注解,后面再引入
//@RequiresPermissions("${moduleName}:${pathName}:list")
4.3.2. 启动逆向工程
启动RenrenApplication:
启动成功,监听端口号为80。浏览器访问,点击renren-fast,出现生成界面,可以看到数据表
选中全部表,点击生成代码按钮,即可生成一个压缩包,被下载下来:
找到压缩包。
4.3.3. 把文件copy到对应工程
-
打开压缩包,压缩包/main/java下的com目录,copy到u-context模块的src/main/java:
效果如下:
-
把压缩包/main/resources下的mapper目录,copy到ucontext模块的src/java/resources目录下:
如下:
4.4、添加common 模块
因为自动生成的代码引用了一些工具类,而我们的项目中没有,所以需要加个common模块添加一些工具类
在uxue项目新建子模块u-common
New Module: 选择Maven
4.4.1、修改u-common模块的依赖
<dependencies>
<!--mybatis-plus DAO层工具 https://mp.baomidou.com/-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.3.0</version>
</dependency>
<!--mybatis-plus整合springboot依赖包-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<!--添加mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!--lombok 不需要写getter,setter方法了-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<!--httpcore 依赖-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.12</version>
</dependency>
<!--commons-lang 依赖 -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- 导入servlet-api 依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
4.4.2、u-common模块添加工具类
添加包:com.offcn.common.utils
从renren-fast项目copy文件:
Constans.java、PageUtils.java、Query.java、R.java、RRException.java
添加包:com.offcn.common.xss
从renren-fast项目copy文件: HTMLFilter.java、SQLFilter.java
修改SQLFilter引入的RRException类所在的包为common下的。
import com.offcn.common.utils.RRException;
修改类Query,把引入类SQLFilter,修改所在包为common下的:
import com.offcn.common.xss.SQLFilter;
最终u-common目录结构如下:
4.4.3、u-context模块引入u-common依赖
<dependency>
<groupId>com.offcn</groupId>
<artifactId>u-common</artifactId>
<version>1.0</version>
</dependency>
4.4.4、解决u-common编译错误
执行mvn install 出现下面的错误:
解决方案,修改模块pom.xml增加maven编译插件,指定jdk版本为1.8
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
4.5、生成其他服务的代码
参考u-context的代码生成方式,生成其他模块的代码
服务名称 | 对应数据库名称 | 模块名称 | 监听端口 |
---|---|---|---|
广告内容服务 | uxue_cms | u-context | 10001 |
会员服务 | uxue_ums | u-member | 10002 |
题目服务 | uxue_qms | u-question | 10003 |
5、模块工程的配置
后台管理模块,每个工程的配置方式基本一样。下面还是以u-context工程为例:
5.1、配置依赖
每个服务到要依赖u-common包
<dependency>
<groupId>com.offcn</groupId>
<artifactId>u-common</artifactId>
<version>1.0</version>
</dependency>
5.2、 工程参数配置
application.yml配置文件:
server:
port: 10001
spring:
datasource:
url: jdbc:mysql://localhost:3306/uxue_cms?serverTimezone=GMT%2B8&characterEncoding=utf-8
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
5.3、在引导类上添加注解
在u-context工程的主启动类(UContextApplication)上添加注解:
@SpringBootApplication
@MapperScan("com.offcn.context.dao")
public class UContextApplication {
public static void main(String[] args) {
SpringApplication.run(UContextApplication.class, args);
}
}
5.4、测试
启动主启动类,访问地址:http://localhost:10001/context/news/list
5.5、 参照u-context完成其他模块
其他模块都按照u-context的方式完成搭建。(其中学习服务和渠道服务省略)
服务名称 | 对应数据库名称 | 模块名称 | 监听端口 |
---|---|---|---|
广告内容服务 | uxue_cms | u-context | 10001 |
会员服务 | uxue_ums | u-member | 10002 |
题目服务 | uxue_qms | u-question | 10003 |
全部服务测试地址:
http://localhost:10001/context/banner/list http://localhost:10002/member/member/list http://localhost:10003/question/question/list
6、搭建注册中心Nacos
6.1 启动nacos服务
Linux/Unix/Mac
启动命令(standalone代表着单机模式运行,非集群模式):
sh startup.sh -m standalone
Windows
启动命令:
cmd startup.cmd -m standalone
或者双击startup.cmd运行文件。
访问:http://localhost:8848/nacos
用户名密码:nacos/nacos
7、注册各个微服务到Nacos
7.1、修改u-context服务的pom.xml引入注册到Nacos所需依赖包
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
7.2、修改配置文件application.yml
spring:
application:
name: u-context
cloud:
nacos:
discovery:
server-addr: localhost:8848
7.3、修改主启动类,添加注解
@SpringBootApplication
@MapperScan("com.offcn.context.dao")
@EnableDiscoveryClient
public class UContextApplication {
public static void main(String[] args) {
SpringApplication.run(UContextApplication.class, args);
}
}
7.4、启动主启动类,查看nacos管理控制台,成功注册
7.5、注册人人管理后台服务到Nacos
配置模块renren-fast模块注册到nacos
7.5.1、引入nacos客户端依赖
修改模块renren-fast的pom.xml
首先定义spring cloud alibaba的版本
<properties>
<spring-cloud-alibaba.version>2.2.0.RELEASE</spring-cloud-alibaba.version>
</properties>
引入spring cloud alibaba的依赖管理:
<dependencyManagement>
<dependencies>
<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>
最后引入springcloudalibaba 注册到nacos的客户端依赖包
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
7.5.2、修改配置文件
修改配置文件application.yml声明应用名称
spring:
application:
name: renren-fast
修改配置文件application-dev.yml,指定nacos服务器地址
spring:
cloud:
nacos:
discovery:
server-addr: http://localhost:8848
7.5.3、修改主启动类RenrenApplication,增加允许注册发现注解
@SpringBootApplication
@EnableDiscoveryClient
public class RenrenApplication {
public static void main(String[] args) {
SpringApplication.run(RenrenApplication.class, args);
}
}
7.5.4、启动主启动类,查看服务是否注册到nacos
7.6、注册其他微服务到Nacos
其他微服务和u-context服务一样的配置,全部注册到Nacos
7.7、注册到nacos失败
有的时候nacos服务器已经启动了,但是依然注册失败,
访问http://localhost:8848/nacos/v1/ns/instance 地址 提示如下:
解决办法:把nacos服务器停掉,删除 nacos/data/protocol 目录
然后重启nacos即可
8、 搭建网关服务
nacos容器内的所有服务,可以直接相互访问。nacos外的服务,为了保证安全,必须通过网关访问后台各个管理模块
8.1、网关依赖配置文件pom.xml:
<?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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.offcn</groupId>
<artifactId>cloud-gateway</artifactId>
<version>1.0</version>
<name>cloud-gateway</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.3.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<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>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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
8.2、application.yml配置路由转发:
server:
port: 8888
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes:
- id: cms-route
uri: lb://u-context
predicates:
- Path=/context/**
filters:
- RewritePath=/(?<segment>.*),/$\{segment}
- id: qms-route # 题目微服务路由
uri: lb://u-question
predicates:
- Path=/question/**
filters:
- RewritePath=/(?<segment>.*),/$\{segment}
- id: ums-route # 用户微服务路由
uri: lb://u-member
predicates:
- Path=/member/**
filters:
- RewritePath=/(?<segment>.*),/$\{segment}
- id: renrenfast-route # 人人后台服务路由
uri: lb://renren-fast
predicates:
- Path=/renren-fast/**
filters:
- RewritePath=/renren-fast/(?<segment>.*),/renren-fast/$\{segment}
application:
name: gateway
8.3、测试网关转发
测试各个微服务经过网关转发调用是否正常
服务名称 | 测试地址 |
---|---|
内容微服务 | http://localhost:8888/context/banner/list |
题目微服务 | http://localhost:8888/question/question/list |
用户微服务 | http://localhost:8888/member/member/list |
人人后台服务 | http://localhost:8888/renren-fast/captcha.jpg?uuid=84d36089-07ae-4201-85c0-8217b032f21c |