整合Nacos配置中心编码实践

282 阅读12分钟

本章节的讲解代码下载地址如下:

本章节的讲解代码下载地址如下:

链接: https://pan.baidu.com/s/1IPLBjQQ7oIyd-vkMmidLug 
提取码: x193


通过前一个章节的讲解,读者应该对 “配置中心” 有了一定的认识。本章节就来讲解如何在应用程序中整合 Nacos 配置中心并且从 Nacos 配置中心获取配置项。通过本章节的学习,读者可以学习到系统架构中引入配置中心后的分布式配置管理方式。

创建基础工程

在整合 Nacos 配置中心前,先来编写一个简单的微服务工程,在这个工程中会使用配置文件的方式存放工程启动时的配置项。之后以该工程为基础去整合 Nacos 配置中心,这样的话,读者在学习时可以更好的理解 Nacos 配置中心的整合过程,也能将两种配置方式进行对比。

该基础工程是在《Nacos 整合之服务注册编码实践》章节源码 spring-cloud-alibaba-nacos-demo 项目的基础上修改的,具体步骤如下所示。

首先,修改项目名称为 spring-cloud-alibaba-nacos-config-base-demo,然后把项目根目录下 pom.xml 文件的 artifactId 修改为 spring-cloud-alibaba-nacos-config-base-demo。

然后修改原来的 nacos-provider-demo 模块修改名称为 nacos-config-demo,并将该 Module 的 parent 标签修改为修改为 spring-cloud-alibaba-nacos-config-base-demo,与上层 Maven 建立好关系。之后,在这个子模块的 pom.xml 文件中加入连接 MySQL 数据库所需的依赖。最终,子节点 nacos-provider-demo 的 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>
    <groupId>ltd.newbee.cloud</groupId>
    <artifactId>nacos-config-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nacos-config-base-demo</name>
    <description>Spring Cloud Alibaba Nacos Base Demo</description>

    <parent>
        <groupId>ltd.newbee.cloud</groupId>
        <artifactId>spring-cloud-alibaba-nacos-config-base-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        
        <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
</project>


接着在 nacos-config-demo 中进行简单的功能编码,首先把该 Spring Boot 项目的启动类名称修改为 ConfigApplication。之后在 ltd.newbee.cloud.api 包包中新建 TestController 类,代码如下:

package ltd.newbee.cloud.api;

import com.alibaba.cloud.nacos.discovery.NacosDiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

@RestController
public class TestController {

    @Resource
    private DataSource dataSource;

    @GetMapping("/dataSource")
    public String dataSource() throws SQLException {
        String datasourceClass = dataSource.getClass().toString();
        Boolean haveConnection = dataSource.getConnection() == null ? false : true;
        return "数据源类型:" + dataSource + ",是否连接成功:" + haveConnection + "";
    }
}


该测试类主要是验证数据源类型,以及是否获取到正确的数据库连接。最后,在配置文件中添加服务名称、注册中心配置、数据库连接配置等内容,最终的 application.properties 文件如下所示:

# 服务名称
spring.application.name=newbee-cloud-config-service
# 环境配置(dev表示开发环境)
spring.profiles.active=dev
# 端口号
server.port=8094

# Nacos注冊中心地址
spring.cloud.nacos.discovery.server-addr=localhost:8848
# Nacos登录用户名(默认为nacos,生产环境一定要修改)
spring.cloud.nacos.username=nacos
# Nacos登录密码(默认为nacos,生产环境一定要修改)
spring.cloud.nacos.password=nacos

# datasource config (MySQL)
spring.datasource.name=newbee-mall-cloud-user-datasource
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/newbee_mall_cloud_user_db?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=60000
spring.datasource.hikari.pool-name=hikariCP
spring.datasource.hikari.max-lifetime=600000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1


最终的工程代码结构如下图所示。

该项目是整合配置中心前的基础代码,主要是创建一个包含常用配置项的微服务实例,配置中包含项目的基础配置项、注册中心配置项以及数据源配置项。接着,启动 ConfigApplication 主类。如果项目启动过程中没有报错,且注册中心已经出现 newbee-cloud-config-service 服务,访问 / dataSource 地址也获取到正确的数据库连接信息,则表示编码成功。

集成 Nacos 配置中心

接下来,笔者将以 spring-cloud-alibaba-nacos-config-base-demo 项目为基础讲解如何在应用程序中整合 Nacos 配置中心获取配置项,然后再来实现动态配置项刷新。

添加 Nacos Config 依赖

打开 nacos-config-demo 的 pom.xml 文件并添加以下两个依赖项。

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>


<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>


项目的配置文件中通常包括数据库连接配置项、日志输出配置项、Redis 连接配置项、服务注册配置项等等内容,比如 spring-cloud-alibaba-nacos-config-base-demo 项目中就包含数据库连接配置项和服务注册配置项。如果把这些配置项存放在配置中心,那么为了保证项目能够正常启动,就必须在数据源实例配置、服务注册流程之前读到所有配置项,因为类似数据源、日志工厂等实例的初始化和服务注册流程都是在项目启动过程中进行的。

基于此种原因,在服务的启动阶段就需要将连接 Nacos 配置中心的配置项加载优先级设置为最高,在 Spring Boot 规范中,bootstrap 配置文件(bootstrap.yml 或者 bootstrap.properties)用来程序引导时执行,应用于更加早期配置信息读取。可以理解成系统级别的一些参数配置,这些参数一般是不会变动的。其加载优先级是高于 application 配置文件(application.yml 或者 application.properties)的。将将连接 Nacos 配置中心的配置项放在到 bootstrap 文件中,能够确保在启动阶段优先执行读取 Nacos 配置中心里所存储的配置项。

添加完依赖,接下来就要配置连接 Nacos 配置中心的参数了。

代码中配置 Nacos Config 连接参数

首先,在 nacos-config-demo 模块的 resource 目录下创建 bootstrap.properties 配置文件。

接下来,在 bootstrap.properties 文件中添加一些连接 Nacos 配置中心的参数,代码及参数释义如下:

# 服务名称
spring.application.name=newbee-cloud-config-service

# 环境配置(dev表示开发环境)
spring.profiles.active=dev

# Nacos配置中心地址
spring.cloud.nacos.config.server-addr=localhost:8848
# 命名空间 默认为PUBLIC
spring.cloud.nacos.config.namespace=dev
# 配置分组组 默认为DEFAULT_GROUP
spring.cloud.nacos.config.group=NEWBEE_CLOUD_DEV_GROUP
# 配置文件格式(有yml json properties等)
spring.cloud.nacos.config.file-extenson=properties
# Nacos配置中心登录用户名(默认为nacos,生产环境一定要修改)
spring.cloud.nacos.config.username=nacos
# Nacos配置中心登录密码(默认为nacos,生产环境一定要修改)
spring.cloud.nacos.config.password=nacos


添加配置文件到 Nacos 配置中心

配置过程演示

打开浏览器并进入 Nacos 控制台页面,如果没有配置自定义命名空间的话,可以点击左侧导航栏中的 “命名空间” 按钮,进入命名空间配置页面,配置内容如下:

主要填写命名空间 ID、命名空间名称和描述。其中命名空间 ID 就是连接配置中心的 spring.cloud.nacos.discovery.namespace 配置项和连接服务注册中心的 spring.cloud.nacos.config.namespace 配置项所要填写的值,笔者将其设置为 dev,如果不填则会自动生成一个长度为 36 的字符串。配置完成后的命名空间列表如下图所示。

之后,点击左侧导航栏中的 “配置列表” 按钮,再切换到 “开发环境” 命名空间(dev)下,如下图所示。

点击配置管理页面右侧的 “+” 按钮,就可以新建一条配置。在这里就可以把原来在 application.properties 文件中的配置项存储到 Nacos 配置中心里了。新建配置的页面如下图所示。

在新建配置页面包含 7 个选项:Data ID、Group、标签、归属应用、说明、配置格式与配置内容,重要的选项释义整理如下:

  1. Data ID:配置的唯一标识,必填项。
  2. Group:指定配置文件的分组,这里设置默认分组 DEFAULT_GROUP 即可,必填项。
  3. 描述:说明配置文件的用途,可不填。
  4. 配置格式:指定 “配置内容” 的类型(文件后缀名),必填项。
  5. 配置内容:程序运行所需的配置项列表,必填项。

在新建配置的页面中,笔者指定了 Data ID 为 newbee-cloud-config-service-dev.properties、Group 为自定义分组 NEWBEE_CLOUD_DEV_GROUP、配置格式为 Properties。在 “配置内容” 输入框中,笔者将端口号、注册中心连接和数据库连接的配置项添加了进去。

DataId 简介

DataId 在 Nacos 配置中心中是配置项的唯一标识符。它用于标识一条配置项信息,并在客户端获取配置信息时使用。

组成 DataId 的完整参数如下:

${prefix}-${spring.profiles.active}.${file-extension}


其中${prefix}默认为应用名称,即 spring.application.name 配置项的值,${spring.profiles.active}是当前选择的环境,${file-extension}是配置内容的数据格式,即配置文件的后缀名。

当前项目中 bootstrap.properties 文件中已经对上述三个配置项做了配置:

# 服务名称
spring.application.name=newbee-cloud-config-service

# 环境配置(dev表示开发环境)
spring.profiles.active=dev

# 配置文件格式(有yml json properties等)
spring.cloud.nacos.config.file-extenson=properties


因此,在拉取配置中心的配置时所读取的 DataId 就是 newbee-cloud-config-service-dev.properties,这也是在新建配置的页面中,笔者将 DataId 指定为 newbee-cloud-config-service-dev.properties 的原因,并不是随意填写的。如果 DataId 填写了其它字符串,程序无法通过配置中心拉取到正确的配置,启动阶段会直接报错的。

如果 spring.profiles.active 配置项并未指定,对应的连接符 “-” 也没了,DataId 的组成参数会变成${prefix}.${file-extension}。比如本章节中的演示代码,如果不配置 spring.profiles.active,则 DataId 就是 newbee-cloud-config-service-dev.properties。

另外,如果不想使用应用名称作为 prefix,可以使用 spring.cloud.nacos.config.prefix 进行自定义。比如本章节中的演示代码,如果增加了一个配置项:

# 服务名称
spring.application.name=newbee-cloud-config-service

# 自定义 DataId 前缀
spring.cloud.nacos.config.prefix=config-service

# 环境配置(dev表示开发环境)
spring.profiles.active=dev

# 配置文件格式(有yml json properties等)
spring.cloud.nacos.config.file-extenson=properties


则 DataId 就是 config-service-dev.properties。如果没有在 Nacos 配置中心没有新建 config-service-dev.properties,则程序启动时无法拉取配置信息会直接报错。

功能验证

一切配置妥当之后,就可以去启动应用程序进行功能验证了。同时,为了测试应用程序能否正确拉取配置中心所创建的远程配置项,就可以删除原来项目中的 application.properties 文件了。

接下来,启动 nacos-config-demo 项目(需保证 Nacos Server 和 MySQL Server 已经正常运行)。启动过程中没有报错,启动日志如下所示:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.3)

2023-02-16 01:34:45.069  WARN 14912 --- [           main] c.a.c.n.c.NacosPropertySourceBuilder     : Ignore the empty nacos configuration and get it based on dataId[newbee-cloud-config-service] & group[NEWBEE_CLOUD_DEV_GROUP]
2023-02-16 01:34:45.084  WARN 14912 --- [           main] c.a.c.n.c.NacosPropertySourceBuilder     : Ignore the empty nacos configuration and get it based on dataId[newbee-cloud-config-service.properties] & group[NEWBEE_CLOUD_DEV_GROUP]
2023-02-16 01:34:45.107  INFO 14912 --- [           main] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-newbee-cloud-config-service-dev.properties,NEWBEE_CLOUD_DEV_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-newbee-cloud-config-service.properties,NEWBEE_CLOUD_DEV_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-newbee-cloud-config-service,NEWBEE_CLOUD_DEV_GROUP'}]
2023-02-16 01:34:45.112  INFO 14912 --- [           main] ltd.newbee.cloud.ConfigApplication       : The following profiles are active: dev
2023-02-16 01:34:45.623  INFO 14912 --- [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=0d83762a-1dbe-395c-91b2-19ae9cc97ba9
2023-02-16 01:34:45.898  INFO 14912 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8094 (http)
2023-02-16 01:34:45.906  INFO 14912 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-02-16 01:34:45.907  INFO 14912 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.56]
2023-02-16 01:34:46.007  INFO 14912 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-02-16 01:34:46.008  INFO 14912 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 885 ms
2023-02-16 01:34:46.904  INFO 14912 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8094 (http) with context path ''
2023-02-16 01:34:46.924  INFO 14912 --- [           main] c.a.c.n.registry.NacosServiceRegistry    : nacos registry, DEFAULT_GROUP newbee-cloud-config-service 192.168.110.131:8094 register finished
2023-02-16 01:34:47.007  INFO 14912 --- [           main] ltd.newbee.cloud.ConfigApplication       : Started ConfigApplication in 3.135 seconds (JVM running for 3.493)
2023-02-16 01:34:47.011  INFO 14912 --- [           main] c.a.c.n.refresh.NacosContextRefresher    : listening config: dataId=newbee-cloud-config-service, group=NEWBEE_CLOUD_DEV_GROUP
2023-02-16 01:34:47.012  INFO 14912 --- [           main] c.a.c.n.refresh.NacosContextRefresher    : listening config: dataId=newbee-cloud-config-service-dev.properties, group=NEWBEE_CLOUD_DEV_GROUP
2023-02-16 01:34:47.013  INFO 14912 --- [           main] c.a.c.n.refresh.NacosContextRefresher    : listening config: dataId=newbee-cloud-config-service.properties, group=NEWBEE_CLOUD_DEV_GROUP


打开浏览器,输入如下请求地址:

http://localhost:8094/dataSource

浏览器输出的内容如下:

数据源类型:HikariDataSource (hikariCP),是否连接成功:true


进入 Nacos 控制台页面,可以看到该服务已经出现在服务列表了。

有些读者可能会问:服务怎么会注册到 public 命名空间了?

这是因为笔者在服务注册的相关配置中并没有对 spring.cloud.nacos.discovery.namespace 和 spring.cloud.nacos.discovery.group 两个参数赋值,而是直接使用了它们默认值,因此 newbee-cloud-config-service 会注册在 public 命名空间且分组名称为 DEFAULT_GROUP。笔者在 bootstrap.properties 文件中指定的是程序与配置中心的连接参数,命名空间和分组的配置名称是 spring.cloud.nacos.config.namespace 和 spring.cloud.nacos.config.group,配置项名称不同,作用也不同,读者们一定要注意区分。

不仅仅是这几条配置项容易混淆,初学者在引入 Nacos 依赖项时也容易搞混。Nacos 组件既可以作为微服务架构中的服务注册中心,也可以作为配置中心。引入 Nacos 的服务发现功能,需要添加的是 spring-cloud-starter-alibaba-nacos-discovery 包,而引入的是 Nacos 的配置管理功能,则需要添加 spring-cloud-starter-alibaba-nacos-config 包。读者们一定要注意这微小的差别,不要弄错了。

到这里,功能验证的结果就出来了。整合 Nacos 配置中心后,项目能够正常启动,数据库连接成功,服务也正确的注册到 Nacos Server。这些都表明整合成功,程序能够正确的通过 Nacos 配置中心远程拉取配置内容了。

总结

本章节中主要讲解在程序中整合 Nacos 配置中心和添加配置文件到 Nacos 配置中心,最终实现远程读取配置文件的功能。后续章节笔者会讲解多配置文件读取和配置动态刷新的开发与编码。希望各位读者能够根据笔者提供的开发步骤顺利地完成本章节的项目修改。当然,读者如果有任何问题或者想要和笔者讨论的内容,都可以在评论区留下看法,笔者会根据读者的反馈和问题继续整理和完善本章节内容。

原文地址 juejin.cn