SpringCloudAlibaba之配置中心Nacos

1. 前言


Nacos 是阿里巴巴新的开源项目,可以快速实现动态服务发现、服务配置、服务元数据及流量管理。

本篇博客以实现配置中心为主。

SpringCloud中也有一个同样优秀的配置中心组件:Spring Cloud Config,以及它对应的高阶组件:Spring Cloud Bus,但是它不提供可视化操作界面,这也是我为什么要学习 Nacos 的原因之一。

如果你也想了解 Spring Cloud ConfigSpring Cloud Bus,那么请前往:SpringCloud之配置中心Config(Git 版),SpringCloud之配置中心Config(高可用),SpringCloud之配置中心Config(消息总线)。个人认为 Nacos 使用起来更加简单,也来说一说个人理解中两者的对比,

核心的相同之处:

  1. 引入依赖
  2. 配置注册中心和配置中心地址
  3. 添加注解

最大的不同之处:

  1. 服务端的搭建方式
  • Eureka Server 是自己手动搭建的;Repository Server 使用远程库搭建私有库
  • Nacos Server 需要通过源码构建或者直接下载的方式搭建;Repository Server 使用 DerbyMySQL
  1. 获取配置的方式
  • Spring Cloud Config 还需专门搭建工程来获取远程库的配置信息
  • Nacos Config 不需要搭建额外的工程,内部配置完成后就可以直接获取配置信息
  1. 通信
  • Spring Cloud Config 想要动态刷新配置功能还需要依赖消息中间件,如 Kafka
  • Nacos Config 不需要额外的消息中间件就可以实现动态刷新配置功能

再来说说 Nacos Server 一些其他的重要信息

部署方式: 三种部署模式,分别对应不同的使用场景

  1. 单机模式:方便本地测试用
  2. 集群模式:适用于生产环境
  3. 多集群模式:用于多数据中心

启动方式: 两种启动方式,分别对应上面部署方式中的单机模式集群模式

  1. Linux / Unix / Mac 系统中单机模式启动需要添加 -m standalone 参数;反之,如果不加 -m standalone 参数则表示是集群模式启动。完整命令:sh startup.sh -m standalone
  2. Windows 系统中目前只支持单机模式启动,直接双击启动脚本文件。或完整命令:cmd startup.cmd

数据源: 两种数据源,分别可以在配置文件中指定

  1. Derby:内嵌在应用中的数据库(目前默认的数据源)
  2. MySQL:免费开源的关系型数据库(版本需要 5.6.5+)

Nacos Server 的版本选择: 目前官网推荐的稳定版本为 1.2.1

Nacos 概念:

  1. 命名空间:用来做不同维度的隔离,比如一个命名空间下是一个单独模块(订单模块,用户模块等),或者一个命名空间下是一组环境(开发,测试,生产等)。
  2. 配置分组:包括一组配置集,也就是多个配置集,可以用来做不同环境的配置隔离。
  3. 配置集:多种不同类型的配置信息的集合称之为配置集,比如RedisMySQL等等不同类型的配置信息都写在了一起,就称它们为一个配置集,那么对应系统中,其实一个配置文件通常就是一个配置集
  4. 配置集 ID:类似于系统中配置文件的文件名,配置集 ID 在同一个配置分组中是唯一的

那么在这里,整个划分就是:使用命名空间区分业务模块,使用配置分组来区分不同环境。


2. 源码


GitHub地址:https://github.com/intomylife/SpringCloud


3. 环境


  • JDK 1.8 +
  • Maven 3.2.x +
  • SpringBoot 2.0.6.RELEASE
  • SpringCloud Finchley.SR2
  • SpringCloudAlibaba 2.0.2.RELEASE

4. 开发工具


  • IntelliJ IDEA

5. 正文


5.1 commons 工程

5.1.1 commons 工程 - POM 文件

<?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>

    <!-- 三坐标 -->
    <groupId>com.zwc</groupId>
    <artifactId>config-commons</artifactId>
    <version>1.0.0</version>

    <!-- 工程名称和描述 -->
    <name>config-commons</name>
    <description>公用工程</description>

    <!-- 打包方式 -->
    <packaging>jar</packaging>

    <!-- 在 properties 下声明相应的版本信息,然后在 dependency 下引用的时候用 ${} 就可以引入该版本 jar 包了 -->
    <properties>
        <!-- 编码 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- jdk -->
        <java.version>1.8</java.version>

        <!-- SpringBoot -->
        <platform-bom.version>Cairo-SR3</platform-bom.version>
        <!-- SpringCloud -->
        <spring-cloud-dependencies.version>Finchley.SR2</spring-cloud-dependencies.version>
        <!-- SpringCloudAlibaba -->
        <spring-cloud-alibaba-dependencies.version>2.0.2.RELEASE</spring-cloud-alibaba-dependencies.version>
    </properties>

    <!-- 加入依赖 -->
    <dependencies>
        <!-- springboot 起步依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <!-- 排除依赖 -->
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- springboot web 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!-- 排除依赖 -->
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- log4j2 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
    </dependencies>

    <!-- 依赖 jar 包版本管理的管理器 -->
    <!-- 如果 dependencies 里的 dependency 自己没有声明 version 元素,那么 maven 就此处来找版本声明。 -->
    <!-- 如果有,就会继承它;如果没有就会报错,告诉你没有版本信息 -->
    <!-- 优先级:如果 dependencies 里的 dependency 已经声明了版本信息,就不会生效此处的版本信息了 -->
    <dependencyManagement>
        <dependencies>
            <!-- SpringBoot -->
            <dependency>
                <groupId>io.spring.platform</groupId>
                <artifactId>platform-bom</artifactId>
                <version>${platform-bom.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- SpringCloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud-dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- SpringCloudAlibaba -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba-dependencies.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>
  • 引入一些共用依赖

5.1.2 commons 工程 - 项目结构

springcloudalibaba-nacos-config/config-commons/
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── zwc
        │           └── core
        └── resources
            └── application.properties

5.2 service 工程

此工程下有四个模块:

应用名称 端口 描述
config-flyway-service 8082 辅助工程(自动创建数据库和表)
config-master-service / 配置中心(这里的配置中心工程其实就是 Nacos 的源码,放入项目中只是为了好找到)
config-order-service 10000 订单服务工程(获取 Nacos Config 中的配置)
config-user-service 11000 用户服务工程(获取 Nacos Config 中的配置)

详细说明:

config-flyway-service: 前言中介绍了 Nacos Server 的数据源有两种,这里使用的是MySQL;而使用MySQL作为数据源后需要建一些基础表和插入一些基础数据,这时就需要手动操作,然而为了方便,我把这些“枯燥”的操作“简化”了:启动一下项目即可。可能唯一需要注意的就是,我本地的MySQL账号密码是root, 123456,如果和你的不一致,那么就在 application.properties 配置文件中更改一下。并且我已经在 Nacos Server 的控制台中添加了一些本篇博客需要的测试数据,也都导出粘贴到此工程中了。

config-master-service: 此工程中仅仅就复制粘贴了 Nacos Server 的源码,这里放入到项目中为了方便获取是一方面原因;还有另一方面是因为,需要在 Nacos Server 的配置文件中指定MySQL为数据源,以及配置MySQL数据库的连接信息,然而为了方便,我已经在 Nacos Server 的源码中改好了这些配置信息。可能唯一需要注意的就是,我本地的MySQL账号密码是root, 123456,如果和你的不一致,那么就在 nacos-1.2.1/distribution/conf/application.properties 配置文件中的 25,26 行更改一下。nacos-1.2.1/distribution/conf/application.properties 作为源码构建后的默认配置文件,所以这里先在源码中修改对应的配置信息,从而方便配合在后面使用脚本来快速启动 Nacos Server 服务。

config-order-service / config-user-service: 都作为获取 Nacos Config 中配置的工程,为什么需要两个:① 可以更好的理解命名空间的概念;② 可以更好的理解配置集以及配置集权重的概念


其他补充说明:

  • SpringCloudAlibaba 源码地址:https://github.com/alibaba/spring-cloud-alibaba
  • Nacos Server 源码地址:https://github.com/alibaba/nacos
  • Nacos Server 源码下载地址:https://github.com/alibaba/nacos/releases
  • Nacos Server 源码加速下载地址:https://gitee.com/mirrors/Nacos/releases
  • Nacos 官方文档地址:https://nacos.io/zh-cn/docs/what-is-nacos.html

5.2.1 config-flyway-service

5.2.1.1 config-flyway-service - POM 文件

<?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.zwc</groupId>
        <artifactId>config-service</artifactId>
        <version>1.0.0</version>
    </parent>

    <!-- 三坐标 -->
    <groupId>com.zwc</groupId>
    <artifactId>config-flyway-service</artifactId>
    <version>1.0.0</version>

    <!-- 工程名称描述 -->
    <name>config-flyway-service</name>
    <description>辅助工程(自动创建数据库和表)</description>

    <!-- 打包方式 -->
    <packaging>jar</packaging>

    <!-- 在 properties 下声明相应的版本信息,然后在 dependency 下引用的时候用 ${} 就可以引入该版本 jar 包了 -->
    <properties>
        <!-- ali 连接池 -->
        <druid.version>1.1.9</druid.version>
    </properties>

    <!-- 加入依赖 -->
    <dependencies>
        <!-- 数据库访问依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- mysql 依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- ali 连接池依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!-- 数据库版本管理 依赖 -->
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>
    </dependencies>

    <!-- 插件依赖 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  • 此工程的作用和目的就是为了自动创建数据库和表,所以引入数据库flyway相关依赖

5.2.1.2 config-flyway-service - application.properties 配置文件

# 端口
server.port=8082


# 数据源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/nacos_config?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=PRC&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456


## flyway    注:可以完全不用配置
### sql 脚本的位置,默认为 classpath:db/migration。可手动指定
#spring.flyway.locations=classpath:db/migration
###  指定数据源,如果没有指定的话,将使用配置的主数据源
#spring.flyway.url=jdbc:mysql://127.0.0.1:3306/nacos_config?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=PRC&useSSL=false
### Flyway 管理的 Schema 列表,区分大小写。默认连接对应的默认 Schema
### 如果这里明确指定了库名,那么在 spring.flyway.url 连接中指定的库名将无效
#spring.flyway.schemas=nacos_config
### 用户名
#spring.flyway.user=root
### 密码
#spring.flyway.password=123456
### 开启,默认开启
#spring.flyway.enabled=true
  • 配置了连接数据库的基本信息,如果账号密码与你的不一致记得修改一下
  • 由于flyway默认会取数据源的配置信息,所以这里关于flyway的配置全部注释,主要为了如果是使用我的源代码测试,数据源的信息可以少改一个地方,我的本地MySQL密码是 123456,大家可能和我不一样

5.2.1.3 config-flyway-service - 自动创建数据库

package com.zwc.flyway.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @ClassName InitDatabaseConfig
 * @Desc TODO   自动创建数据库
 * @Date 2020/6/21 8:38 PM
 * @Version 1.0
 */
@Configuration
public class InitDatabaseConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(InitDatabaseConfig.class);

    /**
     * 读取配置文件中数据库的连接信息
     */
    /**
     * 驱动名称
     */
    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
    /**
     * 地址
     */
    @Value("${spring.datasource.url}")
    private String url;
    /**
     * 用户名
     */
    @Value("${spring.datasource.username}")
    private String username;
    /**
     * 密码
     */
    @Value("${spring.datasource.password}")
    private String password;


    /*
      * @ClassName InitDatabaseConfig
      * @Desc TODO  创建数据库
      * @Date 2020/6/22 8:58 AM
      * @Version 1.0
     */
    @Bean(name = "dataSource")
    public DataSource dataSource() {
        LOGGER.info("==================================== InitDatabaseConfig -> dataSource -> 开始创建数据库 ====================================");
        // 数据库连接对象
        Connection connection = null;
        Statement statement = null;
        try {

            // 如果尝试去连接不存在的数据库会报错,所以这里连接的时候不带数据库名称
            String connectionUrl = url.replace(("/" + (url.substring(0, url.indexOf("?"))).substring(((url.substring(0, url.indexOf("?"))).lastIndexOf("/")) + 1)), "");
            // 从连接地址中截取出数据库名称
            String databaseName = (url.substring(0, url.indexOf("?"))).substring(((url.substring(0, url.indexOf("?"))).lastIndexOf("/")) + 1);

            // 设置驱动
            Class.forName(driverClassName);
            // 连接数据库
            connection = DriverManager.getConnection(connectionUrl, username, password);
            statement = connection.createStatement();

            // 创建数据库
            statement.executeUpdate("create database if not exists `" + databaseName + "` default character set utf8mb4 COLLATE utf8mb4_general_ci");

        }catch (Exception e) {
            e.printStackTrace();
            LOGGER.info("==================================== InitDatabaseConfig -> dataSource -> 创建数据库出错:" + e.getMessage() + " ====================================");
        }finally {
            try {
                // 关闭连接
                statement.close();
                connection.close();
            }catch (SQLException e) {
                LOGGER.info("==================================== InitDatabaseConfig -> dataSource -> 关闭数据库出错:" + e.getMessage() + " ====================================");
            }
            LOGGER.info("==================================== InitDatabaseConfig -> dataSource -> 创建数据库结束 ====================================");
        }

        // 创建数据源
        DruidDataSource druidDataSource = new DruidDataSource();
        // 设置数据源
        druidDataSource.setDriverClassName(driverClassName);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        // 返回数据源
        return druidDataSource;
    }

}
  • 使用@Configuration标注自定义配置类,在应用上下文加载时初始化

5.2.1.4 config-flyway-service - 自动新建数据表

由于引入了flyway-core依赖,所以只需要把初始化 sql 放在 flyway 默认会去读取的db/migration目录中,就可以了。具体内容可在源码中查看,就不粘贴出来占篇幅了。

5.2.1.5 config-flyway-service - 启动项目

  1. 确认并修改好数据库的连接信息后,启动项目;发现项目启动后就自动停止了,只要不报错,这里就是正常的,控制台会打印如下日志信息:
2020-07-05 16:36:25.254  INFO 6046 --- [           main] c.zwc.flyway.config.InitDatabaseConfig   : ==================================== InitDatabaseConfig -> dataSource -> 开始创建数据库 ====================================
2020-07-05 16:36:25.462  INFO 6046 --- [           main] c.zwc.flyway.config.InitDatabaseConfig   : ==================================== InitDatabaseConfig -> dataSource -> 创建数据库结束 ====================================
  1. 这时到MySQL图形化连接工具中刷新本地库,发现多了一个nacos_config数据库,打开数据库,可以看到一些基础表已经被自动创建出来了
  2. 那么,config-flyway-service 工程的作用就到此结束了

5.2.2 config-master-service

此工程中只有 Nacos Server 的源码,就没有太多搭建上的说明,唯一需要注意的就是上面提到过的数据库连接账号密码,如果你的不是root, 123456,那么就去修改一下。

但是此处需要着重说明的是如何快速构建这个源码,当然,Nacos 官方文档中已经写的很详细了,这里就锦上添花一波,把一些命令再“封装”一下,达到一行命令就能快速启动 Nacos Server 服务的效果。

这里分别为本地快速开发测试以及日常使用两种不同的场景编写了脚本,放在了项目的 script 目录中

springcloudalibaba-nacos-config/
├── config-commons
├── config-service
└── script
    ├── daily-use
    │   ├── nacos-start.sh
    │   └── nacos-stop.sh
    └── quick-start
        ├── nacos-install.bat
        ├── nacos-install.sh
        ├── nacos-start.bat
        ├── nacos-start.sh
        ├── nacos-stop.bat
        └── nacos-stop.sh

5.2.2.1 config-master-service - quick-start 目录 - 快速开始

  1. 使用IDEA打开 springcloudalibaba-nacos-config 项目
  2. 点击IDEA底部的Terminal终端入口
  3. 进入到项目根目录
MacBook-Pro:springcloudalibaba-nacos-config zouwencong$ pwd
/Users/zouwencong/JavaWork/my_spring_cloud/SpringCloud/springcloudalibaba-nacos-config
MacBook-Pro:springcloudalibaba-nacos-config zouwencong$ ls -all
total 24
drwxr-xr-x   7 zouwencong  staff   224 Jul  2 09:34 .
drwxr-xr-x  18 zouwencong  staff   576 Jul  3 13:54 ..
-rw-r--r--@  1 zouwencong  staff  8196 Jul  2 09:54 .DS_Store
drwxr-xr-x  10 zouwencong  staff   320 Jul  5 16:48 .idea
drwxr-xr-x  10 zouwencong  staff   320 Jul  2 10:19 config-commons
drwxr-xr-x  13 zouwencong  staff   416 Jul  5 15:11 config-service
drwxr-xr-x   5 zouwencong  staff   160 Jun 22 17:51 script
MacBook-Pro:springcloudalibaba-nacos-config zouwencong$ 
  1. 如果是Mac用户,先输入命令chmod +x script/quick-start/nacos-install.sh,然后再输入命令./script/quick-start/nacos-install.sh
  2. 如果是Windows用户,输入命令script\quick-start\nacos-install.bat
  3. 第一次构建时间会相对久一点,我自己这里用了大概两三分钟的样子,因为要到Maven中去下载SpringCloudAlibaba的相关依赖
  4. 如果是Mac用户,执行完对应命令后会有如下日志(截取最后关键部分):
...省略部分...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 31.655 s
[INFO] Finished at: 2020-07-05T19:41:33+08:00
[INFO] Final Memory: 110M/1630M
[INFO] ------------------------------------------------------------------------
...省略部分...
nacos is starting with standalone
nacos is starting,you can check the /Users/zouwencong/Downloads/SpringCloud-master/springcloudalibaba-nacos-config/config-service/config-master-service/nacos-1.2.1/distribution/target/nacos-server-.2.1/nacos/logs/start.out
[INFO] ----------------------------- end --------------------------------------
  1. 如果是Windows用户,执行完对应的命令后会有如下日志(截取最后关键部分):
...省略部分...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:09 min
[INFO] Finished at: 2020-07-05T20:02:30+08:00
[INFO] ------------------------------------------------------------------------
...省略部分...
2020-07-05 20:02:38,296 INFO Nacos started successfully in stand alone mode.

2020-07-05 20:02:38,416 INFO Initializing Servlet 'dispatcherServlet'

2020-07-05 20:02:38,425 INFO Completed initialization in 8 ms
  1. 这样 Nacos Server 就启动成功了,访问 Nacos Server 主页面:http://localhost:8848/nacos
  2. 账号密码:nacos, nacos
  3. 这里对应还有停止的脚本
  4. 如果是Mac用户,先输入命令chmod +x script/quick-start/nacos-stop.sh,然后再输入命令./script/quick-start/nacos-stop.sh
  5. 如果是Windows用户,发现当前Terminal框并没有可输入的地方了,所以这里想停止的话就先点击+ (New Session)按钮,然后再输入命令script\quick-start\nacos-stop.bat
  6. 那么如果想再启动,因为这里都构建过了,所以分别使用启动的脚本
  7. 如果是Mac用户,先输入命令chmod +x script/quick-start/nacos-start.sh,然后再输入命令./script/quick-start/nacos-start.sh
  8. 如果是Windows用户,输入命令script\quick-start\nacos-start.bat

5.2.2.2 config-master-service - daily-use 目录 - 日常使用

我们可能以后项目中经常会用到 Nacos Server 服务,就像RedisMySQL一样,当做一个服务来启动,那么就先把刚刚编译构建后的目录(config-master-service/nacos-1.2.1/distribution/target/nacos-server-1.2.1/nacos)复制到本地。由于是作为日常使用的服务,所以再来设置一下日志目录

  1. 打开刚刚复制目录(config-master-service/nacos-1.2.1/distribution/target/nacos-server-1.2.1/nacos)下的 conf/application.properties 配置文件
  2. Ctrl + F 搜索server.tomcat.basedir
  3. 后面就可以指定存放日志的目录路径

由于Windows中启动 Nacos Server 不需要指定参数,所以在刚刚复制目录(config-master-service/nacos-1.2.1/distribution/target/nacos-server-1.2.1/nacos)下的 bin 目录中的 .bat 脚本可以直接双击使用;而Mac中为了方便,这里也写了一个日常使用的脚本,如何使用

  1. 复制 springcloudalibaba-nacos-config 项目中的 script/daily-use/nacos-start.sh 脚本文件和 script/daily-use/nacos-stop.sh 脚本文件到桌面
  2. 赋值执行权限:chmod +x nacos-start.shchmod +x nacos-stop.sh
  3. 右键nacos-start.sh文件
  4. 打开方式->其他...
  5. 启用:选择所有应用程序
  6. 勾选始终以此方式打开
  7. 点击实用工具
  8. 双击终端
  9. nacos-stop.sh 也同样设置一遍
  10. 都设置好后,现在只需要双击即可启动停止 Nacos Server 服务
  11. 当然,你具体会把构建后的目录复制到哪我是不知道的,所以脚本中的具体目录需要对应的修改一下
  12. nacos-start.sh -> 第 20 行
  13. nacos-stop.sh -> 第 8 行

5.2.2.3 config-master-service - 启动 Nacos Server

  1. Nacos Server 启动成功后,访问 http://localhost:8848/nacos
  2. 账号密码:nacos, nacos
  3. 由于在 config-flyway-service 工程中已经把本篇博客需要的测试数据执行了,所以先来看看都有些什么
  4. 访问 http://localhost:8848/nacos/#/namespace(命名空间)
    SpringCloudAlibaba之配置中心Nacos_第1张图片
  5. 此处就为每一个服务工程都新建了一个命名空间
  6. 访问 http://localhost:8848/nacos/#/configurationManagement(配置管理)
    SpringCloudAlibaba之配置中心Nacos_第2张图片
  7. 此处就为每一个服务工程的每一套环境都新建了多个配置集
  8. 点击详情按钮可以查看每一个配置集的具体配置信息

5.2.3 config-order-service

5.2.3.1 config-order-service - POM 文件

<?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.zwc</groupId>
        <artifactId>config-order-service</artifactId>
        <version>1.0.0</version>
    </parent>

    <!-- 三坐标 -->
    <groupId>com.zwc</groupId>
    <artifactId>config-order-service-core</artifactId>
    <version>1.0.0</version>

    <!-- 工程名称描述 -->
    <name>config-order-service-core</name>
    <description>订单服务工程 - 核心</description>

    <!-- 打包方式 -->
    <packaging>jar</packaging>

    <!-- 在 properties下声明相应的版本信息,然后在dependency下引用的时候用 ${} 就可以引入该版本jar包了 -->
    <properties>

    </properties>

    <!-- 加入依赖 -->
    <dependencies>
        <!-- commons 工程依赖 -->
        <dependency>
            <groupId>com.zwc</groupId>
            <artifactId>config-commons</artifactId>
            <version>1.0.0</version>
        </dependency>

        <!-- api 工程依赖 -->
        <dependency>
            <groupId>com.zwc</groupId>
            <artifactId>config-order-service-api</artifactId>
            <version>1.0.0</version>
        </dependency>

        <!-- 提供者消费者 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- 配置中心 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
    </dependencies>

    <!-- 插件依赖 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  • 加入 spring-cloud-starter-alibaba-nacos-discovery 依赖,表示会向 Nacos Server 中注册自己
  • 加入 spring-cloud-starter-alibaba-nacos-config 依赖,表示会到 Nacos Server 中获取配置文件

5.2.3.2 config-order-service - bootstrap.yml 配置文件

spring:
  application:
    # 应用名称
    name: order-config
  cloud:
    nacos:
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        # 用户名
        username: nacos
        # 密码
        password: nacos
        # 命名空间:用来区分不同的服务模块
        namespace: order-config-namespace
        # 分组:用来区别不同的环境(dev, stg, prd)
        group: dev
        # 配置内容的数据格式:在配置中心以 .yml 结尾的 Data Id(Data Id:配置集,类似于文件名)
        file-extension: yml
        # 扩展配置,加载多配置集:用在把配置文件拆分成多个的场景。
        extension-configs[0]:
          refresh: true
          data-id: redis.yml
          group: stg
        # extension 越往后权重越高
        extension-configs[1]:
          refresh: true
          data-id: mysql.yml
          group: dev
  • Nacos Config 相关的配置文件必须写在bootstrap.propertiesbootstrap.ym中,因为这里需要获取的是远程的配置信息,而bootstrap.xxx配置文件是用于应用程序上下文的引导阶段
  • 注意此处指定配置中心地址的端口为 8848 也就是 Nacos Server 的服务端口
  • 注意这里还配置了 Nacos Server 的用户名和密码,那是因为我在 config-master-service/nacos-1.2.1/distribution/conf/application.properties 配置文件中把 nacos.core.auth.enabled 设置为了 true,其实默认是 false 关闭的;开启后这里必须指定有效的用户名和密码,否则会报错
  • namespace:命名空间,在前言中提到过,会使用命名空间区分业务模块。如果不指定,那么默认就是在 public 命名空间下。命名空间 ID 是全局唯一的,可在 Nacos Server 控制台中添加,当前 Nacos Server 1.2.1 版本中命名空间还可以手动指定
  • group:配置分组,在前言中提到过,会使用配置分组来区分不同环境。如果不指定,那么默认就是在 DEFAULT_GROUP 组中。相同的组名就可以出现多次,毕竟一组中是可以有多个配置集的,同样可在 Nacos Server 控制台中添加
  • file-extension:指定配置集的名称是以什么结尾。如果不指定,那么默认就是找 .properties 结尾的配置集
  • 那么,有了上面的这些配置信息,当项目启动后,就会到 Nacos Config 中的 order-config-namespace 命名空间下的 dev 分组下找到以 .yml 结尾的配置集,这些配置集中的配置信息就会被程序获取
  • 以及这里还可以指定扩展配置集,为何还需要扩展配置集,因为上面只会读取固定格式的配置集:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
  • 扩展配置集中指定的 extension-configs.group 配置分组权重大于原本的 config.group 配置分组
  • 扩展配置集越往后的权重越高
  • 另一个用户服务工程(config-user-service) 的配置信息类似于它,当然除了会拥有自己唯一的应用名称命名空间外,还有一处关键点:用户服务工程(config-user-service) 的扩展配置集的 extension-configs[1].group 指定的是 stg 环境,此处用来体现上面所说的权重

5.2.3.3 config-order-service - application.yml 配置文件

spring:
  # 选择环境
  profiles:
    ## 动态从 bootstrap.yml 中获取当前环境
    active: ${spring.cloud.nacos.config.group}
    ## 开发环境
    ## active: dev
    ## 测试环境
    ## active: stg
    ## 生产环境
    ## active: prd

  cloud:
    nacos:
      discovery:
        # 注册中心地址
        server-addr: 127.0.0.1:8848
        # 用户名
        username: nacos
        # 密码
        password: nacos
        # 命名空间:用来区分不同的服务模块
        namespace: order-config-namespace

---

# 端口
server:
  port: 10000

spring:
  ## 开发环境
  profiles: dev

  ## 单个环境经常改动的配置

---

# 端口
server:
  port: 10000

spring:
  ## 测试环境
  profiles: stg

  ## 单个环境经常改动的配置

---

# 端口
server:
  port: 10000

spring:
  ## 生产环境
  profiles: prd

  ## 单个环境经常改动的配置

---
  • 注意此处配置注册中心地址的端口为 8848 也就是 Nacos Server 的服务端口
  • 注意这里还配置了 Nacos Server 的用户名和密码,那是因为我在 config-master-service/nacos-1.2.1/distribution/conf/application.properties 配置文件中把 nacos.core.auth.enabled 设置为了 true,其实默认是 false 关闭的;开启后这里必须指定有效的用户名和密码,否则会报错
  • 使用 --- 分隔符来分隔多套环境的配置信息
  • 使用 spring.profiles.active 来指定使用哪套环境的配置信息
  • 另一个用户服务工程(config-user-service) 的配置信息类似于它,当然除了会拥有自己唯一的命名空间外,就是端口不一致了,此处端口为 10000,另一个端口为 11000。就不再赘述

5.2.3.4 config-order-service - controller 前端控制器

package com.zwc.order.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName OrderController
 * @Desc TODO   读取远程配置信息
 * @Date 2020/7/2 6:14 PM
 * @Version 1.0
 */
@RestController
@RefreshScope
public class OrderController {

    @Value("${order.data.info}")
    String dataInfo;

    @Value("${order.group}")
    String group;

    @Value("${order.ext.name}")
    String extName;

    /*
      * @ClassName OrderController
      * @Desc TODO  读取远程配置信息
      * @Date 2020/7/2 6:16 PM
      * @Version 1.0
     */
    @GetMapping(value = "/info")
    public String info() {
        return "dataInfo: " + dataInfo + ", group: " + group + ", extName: " + extName;
    }

}
  • 使用 @Value("${}") 注解读取配置信息,并输出
  • 添加了 @RefreshScope 注解表示打开动态刷新功能

5.2.3.5 config-order-service - 启动类

package com.zwc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ConfigOrderServiceCoreApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigOrderServiceCoreApplication.class, args);
    }

}
  • 添加 @EnableDiscoveryClient 注解表示此服务要向注册中心注册自己

5.2.3.6 config-order-service - 启动项目

  1. 项目启动成功后,首先查看控制台打印的日志,有部分如下(在最上面一点):
2020-07-05 21:26:00.654  INFO 7493 --- [           main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='order-config-dev.yml,dev'}, NacosPropertySource {name='order-config.yml,dev'}, NacosPropertySource {name='order-config,dev'}, NacosPropertySource {name='mysql.yml,dev'}, NacosPropertySource {name='redis.yml,stg'}]}
2020-07-05 21:26:00.657  INFO 7493 --- [           main] c.z.ConfigOrderServiceCoreApplication    : The following profiles are active: dev
  1. 可以发现,加载了一些配置集,其中就有 Nacos Server 控制台中新建的 order-config.yml 配置集,并且还是属于 dev 配置分组;此外,还加载了指定的扩展配置集
  2. 这时,访问 http://localhost:10000/info 看到输出内容dataInfo: order-config-dev.yml, group: dev, extName: mysql-dev
  3. 那么,对照着 Nacos Server 控制台中的配置列表中的配置集,以及服务工程中的 bootstrap.yml 配置文件来分析输出内容,可以得出:在默认的配置集中有的配置信息,权重较高;在有多个扩展的配置集的情况下,越往后写的扩展配置集权重越高
  4. 现在就把 config-user-service 服务也启动起来
  5. 项目启动成功后访问 http://localhost:11000/info 看到输出内容dataInfo: user-config-dev.yml, group: stg, extName: mysql-stg
  6. 同样都是配置的 dev 分组,却有部分 stg 配置分组中的配置信息,那是因为,在 config-user-service 服务工程中配置的扩展配置集中,最后指定的是 stg 分组
  7. 再来测试一下动态刷新功能,打开 配置列表页面,编辑 order-config-namespace 命名空间下的 dev 分组中的 order-config.yml 配置集信息
  8. 点击编辑按钮,修改配置内容如下
order:
  data:
    info: order-config-dev666.yml
  1. 依次点击 发布 -> 确认发布 -> 确定 按钮
  2. 再次访问 http://localhost:10000/info 看到输出内容dataInfo: order-config-dev666.yml, group: dev, extName: mysql-dev
  3. 证明动态刷新功能成功

5.3 service 工程 - 项目结构

springcloudalibaba-nacos-config/config-service/
├── config-flyway-service
│   ├── mvnw
│   ├── mvnw.cmd
│   ├── pom.xml
│   └── src
├── config-master-service
│   ├── mvnw
│   ├── mvnw.cmd
│   ├── nacos-1.2.1
│   └── pom.xml
├── config-order-service
│   ├── config-order-service-api
│   ├── config-order-service-core
│   ├── mvnw
│   ├── mvnw.cmd
│   └── pom.xml
├── config-user-service
│   ├── config-user-service-api
│   ├── config-user-service-core
│   ├── mvnw
│   ├── mvnw.cmd
│   └── pom.xml
├── mvnw
├── mvnw.cmd
└── pom.xml

6. 把项目使用 IntelliJ IDEA 打开

  1. 把项目从 GitHub 中下载到你的本地
  2. 打开 IntelliJ IDEA
  3. 点击 File -> Open
  4. 打开你下载到本地的项目目录
  5. springcloudalibaba-nacos-config(选择打开此工程)
  6. 如果是高版本的 IntelliJ IDEA,则在右下角会提示有一些工程可以导入,那么选择一键导入就可以了
  7. 如果是低版本的 IntelliJ IDEA,则手动来导入
  8. 点击右侧 Maven Projects 入口
  9. 点击 + (Add Maven Projects)
  10. 分别选择 config-commons 工程和 config-service 工程的 pom.xml 文件,点击 Open 按钮


希望能够帮助到你

over




你可能感兴趣的:(SpringCloud,SpringBoot,SpringCloud,Nacos)