简易SpringCloud项目构建过程(上)
上篇主要包括数据库设计说明、父级工程创建与配置、服务注册中心、统一配置中心、Common工程5个部分。下篇包括数据接口服务提供者、数据消费者工程、网关工程3个部分。
源码地址:https://github.com/kinglong198404/spring-cloud-architecture.git下的spring-cloud-simple。
1. 数据库设计
1.1 数据表清单
序号 |
表名 |
描述 |
备注 |
1 |
user |
用户表 |
|
2 |
knowlege_base |
知识库表 |
模块三 知识百科(攻略) |
1.2 user(用户表)
列名 |
数据类型 |
数据长度 |
是否为空 |
默认值 |
备注 |
id |
int |
|
NO |
|
主键id |
username |
varchar |
32 |
NO |
|
用户名 |
nickname |
varchar |
32 |
YES |
|
昵称 |
password |
varchar |
64 |
NO |
|
密码 |
|
varchar |
32 |
NO |
|
邮箱 |
1.3 knowlege_base(知识库)
列名 |
数据类型 |
数据长度 |
是否为空 |
默认值 |
备注 |
id |
bigint |
|
NO |
|
主键id |
title |
varchar |
64 |
YES |
|
标题 |
content |
text |
65535 |
YES |
|
内容 |
tag |
varchar |
16 |
NO |
|
标签 |
author |
varchar |
32 |
YES |
|
作者 |
user_id |
int |
|
YES |
|
用户id |
create_time |
datetime |
|
NO |
CURRENT_TIMESTAMP |
无注释 |
edit_time |
datetime |
|
YES |
CURRENT_TIMESTAMP |
无注释 |
is_deleted |
tinyint |
|
NO |
0 |
是否已删除。0 未删除,1 已删除。 |
2. 父工程(klblog-parent)
2.1 创建父工程
1)启动IDEA,File -->New -->Project,选择maven,选择Project SDK版本为1.8,点击next
2)填写项目名称,选择项目保存路径,填写项目相关的信息,-->finish
3)删除src目录
2.2 配置父工程
修改pom.xml文件
2.2.1 添加对spring boot 的父依赖
<groupId>com.klfront.klblog</groupId>
<artifactId>klblog-parent</artifactId>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.13.RELEASE</version>
<relativePath/>
</parent>
<pluginRepositories>
<!--解决报错:spring-boot-starter-parent:2.x.x.RELEASE not found-->
<pluginRepository>
<id>repository.spring.release</id>
<name>Spring GA Repository</name>
<url>https://repo.spring.io/plugins-release/</url>
</pluginRepository>
</pluginRepositories>
A.spring-boot-starter-parent继承自spring-boot-dependencies,相关插件的版本管理都在其中。包括mysql-connector-java、lombok、logback-core、log4j2、junit等插件的版本管理。
B.spring-boot-starter-parent包含了属性资源的配置,在resources节点下
包括对**/application*.yml、**/application*.yaml、**/application*.properties等属性资源文件的include和exclude的支持。
C.spring-boot-starter-parent已经有了一些插件管理的配置,在pluginManagement节点下
包括:maven-compiler-plugin、maven-failsafe-plugin、maven-jar-plugin、maven-war-plugin、exec-maven-plugin、maven-resources-plugin(默认分解符@)、git-commit-id-plugin、spring-boot-maven-plugin、maven-shade-plugin、lifecycle-mapping等
2.2.2 插件版本管理配置
主要配置在spring-boot-dependencies中没有涉及的依赖组件的版本管理,包括spring-cloud-dependencies、com.alibaba.druid、com.alibaba.fastjson、mybatis-spring-boot-starter
<!-- 相关插件的版本管理 -->
<dependencyManagement>
<dependencies>
<!-- spring-cloud和spring-boot 版本匹配 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 数据库相关-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
</dependencies>
</dependencyManagement>
2.2.3 配置build节点
<build>
<finalName>klblog</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimit>$</delimit>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
说明:
plugins这里主要是配置maven打包插件。
resources主要用于配置打包资源文件,默认情况maven只打包src/main/resource下的资源。
filtering 开启过滤,打包时用指定的参数替换配置文件中的符号
3. 服务注册中心(eureka-server)
3.1 创建EurekaServer工程
1.在父工程项目上右键new-->module。
这样在pom.xml中自动会配置继承父级工程,不用手动去修改。
2.选择Maven-->next,填写Name为eureka-server,点击finish完成创建。
3.2 配置EurekaServer工程
3.2.1 修改pom.xml
pom文件中引入Eureka服务端依赖。
<dependencies>
<!--eureka-server服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!--这个插件,可以将应用打包成一个jar包,内含嵌入式tomcat-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.2.2 配置application.yml文件
将自动生成的application.properties更改为application.yml文件
server:
port: 8761 #指定该Eureka实例的端口
spring:
application:
name: eureka-server #服务名称,自定义
eureka:
instance:
#hostname: eureka8761 #eureka服务端所在的服务器域名
hostname: localhost
client:
registerWithEureka: false #禁止注册自身
fetchRegistry: false #自己就是注册中心,所以关闭从注册中心拉取服务列表。
serviceUrl:
defaultZone: http://localhost:8762/eureka/ #多eureka服务,配置其他节点 server:
renewalPercentThreshold: 0.49 #设置心跳正常的阀值,默认为1,测试时可以调低
3.3 创建启动类
添加启动类EurekaServerApplication,为其添加注解@EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
在EurekaServerApplication上右键--> Run EurekaServerApplication,启动成功,在浏览器访问http://localhost:8761,如下图所示
3.4 报错处理
SpringBootApplication无法解析,import org.springframework.boot.SpringApplication;中的springframework报红,或者spring-cloud-starter-netflix-eureka-server报错,提示找不到。可能是maven本地仓储没有相应的依赖jar包。
步骤1:
如下图,父工程的pom.xml文件上->右键->maven->Reload project,重新加载项目。
步骤2:在IDEA右侧maven工具栏对父工程执行install命令,将工程安装到maven本地仓储。安装过程中会自动加载需要的依赖的jar包到本地仓储(C:\Users\[用户名]\.m2\repository)下。
启动工程,访问http://localhost:8761/,显示如下,eureka-server构建成功。
4. 配置中心(config-server)
统一在本工程进行通用的配置,如eureka-server配置、数据库连接配置。其他微服务工程在bootstrap.yml中配置config服务地址和选项,从本服务获取通用部分的配置。
方式一:直接在本服务的resource下配置base.yml和datasource.yml。(需要在application.yml中配置profiles:active: native)
方式二:在gitlab上维护base.yml和datasource.yml文件。 本服务工程与gitlab建立关联,从gitlab获取配置信息。
本示例项目使用 方式一。
4.1 创建ConfigServer工程
4.1.1 创建工程
在父工程项目上右键new-->module,创建config-server微服务工程。
4.1.2 配置pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
<build>
<finalName>config-server</finalName>
<plugins>
<!--这个插件,可以将应用打包成一个jar包,内含嵌入式tomcat-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
4.1.3 配置application.yml
server:
port: 8888
spring:
application:
name: config-server
profiles:
active: native #使用本地配置资源,而不是git
4.2 提供通用配置文件
在resources目录下创建base.yml和datasource.yml配置文件。
4.2.1 base.yml(基础配置,eureka服务地址等)
注意以下配置项中虽然没有spring的子项需要配置,仍然需要配置至少一个spring.profiles项。否则环境(开发、测试、生产等)的匹配失效,只有最后一个环境的(这里是prod)eureka配置会生效,前面的配置都会被覆盖。
spring:
profiles:
active:
- dev
---
spring:
profiles: dev
eureka:
profiles: dev #开发环境
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
---
spring:
profiles: prod
eureka:
profiles: prod #生产环境
client:
service-url:
defaultZone: http://www.klfont.com:8761/eureka/,http://www.klfont.com:8762/eureka/
4.2.2 datasource.yml(数据源相关,mybatis、mysql等)
spring:
profiles:
active:
- dev
---
spring:
profiles: dev
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
url: jdbc:mysql://localhost:3306/klblog?useUnicode=true&characterEncoding=utf8
username: king
password: xxxxxx
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
mybatis:
profiles: dev
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径
type-aliases-package: com.klfront.klblog.common.entity # 所有Entity别名类所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射文件
---
spring:
profiles: prod
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
url: jdbc:mysql://www.klfront.com:3306/klblog?useUnicode=true&characterEncoding=utf8
username: king
password: xxxxxx
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
mybatis:
profiles: prod
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径
type-aliases-package: com.klfront.klblog.common.entity # 所有Entity别名类所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射文件
4.3 创建主启动类,添加@EnableConfigServer注解
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
4.4 启动工程,并在浏览器输入地址测试
访问配置信息,如下图所示:
http://localhost:8888/base-dev.yml
http://localhost:8888/datasource-dev.yml
5. Common工程(common)
common工程的作用有以下几个方面:
1)各业务模块微服务都需要依赖的类库,在common的pom.xml中统一配置依赖。
2)各业务模块微服务都需要用到的实体类,统一在common工程定义,避免每个微服务重复定义。
3)各业务模块微服务都会用到的工具类的定义,统一在common工程定义,避免每个微服务重复定义。
这样,各业务模块只需要专注业务处理和数据接口提供。
5.1 pom.xml配置
<dependencies>
<!--web的场景,自动引入了web模块开发需要的相关jar包:spring-boot-starter,spring-boot-starter-tomcat,hibernate-validator,jackson-databind,spring-web,spring-webmvc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--实现AOP日志-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!--swagger接口文档组件-->
<!--1.x版本:http://{ip}:{port}/{server.servlet.context-path}/swagger-ui.html-->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
</dependencies>
5.2 通用实体类
1)数据表对应的实体类
2)通用的数据返回对象类定义
/**
* 通用的数据返回对象
* @param <T>
*/
@Data
@ToString
public class GlobalResponse<T> implements Serializable {
private Integer code;
private String message;
private T data;
private final static Integer SUCCESS_CODE = 200;
private final static Integer LOGIN_FAIL_CODE = 401;
private final static Integer AUTH_FAIL_CODE = 403;
private final static Integer NOT_FOUND_CODE = 404;
private final static Integer COMMON_ERROR = 500;
public final static String LOGIN_FAIL_MESSAGE ="身份验证失败,请先登录!";
public final static String AUTH_FAIL_MESSAGE ="没有访问该接口的权限";
public GlobalResponse(T data){
this.data = data;
}
public static <T> GlobalResponse<T> success(T data){
GlobalResponse<T> res = new GlobalResponse(data);
res.setCode(SUCCESS_CODE);
return res;
}
public static <T> GlobalResponse<T> loginFail(String errorMsg){
GlobalResponse<T> res = new GlobalResponse(null);
res.setCode(LOGIN_FAIL_CODE);
res.setMessage(errorMsg);
return res;
}
public static <T> GlobalResponse<T> authFail(String errorMsg){
GlobalResponse<T> res = new GlobalResponse(null);
res.setCode(AUTH_FAIL_CODE);
res.setMessage(errorMsg);
return res;
}
public static <T> GlobalResponse<T> notfound(String errorMsg){
GlobalResponse<T> res = new GlobalResponse(null);
res.setCode(NOT_FOUND_CODE);
res.setMessage(errorMsg);
return res;
}
public static <T> GlobalResponse<T> error(String errorMsg){
GlobalResponse<T> res = new GlobalResponse(null);
res.setCode(COMMON_ERROR);
res.setMessage(errorMsg);
return res;
}
}
5.3 工具类
FileUtil、MD5Util、UrlEncodeUtil、HtmlExtract等工具类。代码请参考源码。