简易SpringCloud项目构建过程(上)

作者:陆金龙    发表时间:2022-03-23 09:45   

关键词:Eureka服务注册中心  Spring-cloud-config配置中心  

上篇主要包括数据库设计说明、父级工程创建与配置、服务注册中心、统一配置中心、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

 

密码

email

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-parent2.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-cloudspring-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等工具类。代码请参考源码。