SpringCloud 2021 与 Nacos 配置中心集成排雷记录:bootstrap.yml

必须要先吐槽一下阿里的开源,功能挺好,但是文档极差,nacos的文档分散在各个地方,而且没有对应的跳转链接,找起来极其费时。更关键的是还不一样,github上的和官网的文档不同步,对于springboot 2.4以后非常重要的一处变更完全没有提及,github的文档维护也完全是靠好心人提issue,团队跟不上啊


为方便后续查找文中涉及到官方文档的地方我都会附上链接

问题现象就不描述了,如果你使用SpringCloud 2020及以上,在按照官方文档进行Nacos集成的时候会要求配置bootstrap.yml,但是当你按照文档一步一步来,启动项目之后会发现nacos client获取不到应用名,spring.application.name是null,导致无法获取nacos中维护的配置信息,启动失败。

环境

SpringCloud 2021.0.1
SpringCloud Alibaba 2021.0.1.0
SpringBoot 2.6.3
Nacos 2.1.0

附完整POM供参考(集成nacos注册发现及配置管理)

<?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.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.inspur</groupId>
    <artifactId>user-center</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>user-center</name>
    <description>Demo project for user-center</description>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2021.0.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2021.0.1.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

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

        <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>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

原因

先看SpringCloud Alibaba给出的版本兼容图
https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
在这里插入图片描述
自从SpringCloud2020开始,SpringBoot版本就更新到了2.4+,而在SpringBoot2.4这个大版本中有一项非常重要的改动:出于对云原生多配置文件的支持,默认关闭了对bootstrap.yml的使用。
https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#_spring_cloud_config_client
在这里插入图片描述
所以,在SpringCloud2020以后,配置bootstrap.yml都是无效的

解决方案一: 重新启用bootstrap.yml(不推荐)

这种方式相当于将SpringBoot降回之前的使用方式,大概分为两步:

  1. 启用bootstrap.yml支持:spring.cloud.bootstrap.enabled=true
  2. 引入bootstrap组件的依赖(注意版本):org.springframework.cloud:spring-cloud-starter-bootstrap

之后就可以按照正常流程操作了。

https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#config-first-bootstrap
在这里插入图片描述

解决方案二:使用spring.config.import(推荐)

鉴于SpringBoot已经废除了bootstrap引入的方式,我们自然也需要知道新的配置引入怎么用,直接上配置好的application.yml

spring:
  application:
    # 应用名,必填,用于注册nacos
    name: user-center
  cloud:
    nacos:
      config:
        # 启用nacos配置管理
        enabled: true
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        # 所属命名空间id,用于区分开发、测试、生产
        namespace: def37ec7-353f-4a86-a77a-d27897e2429f
        # 配置文件类型
        file-extension: yml
      discovery:
        # 注册中心地址
        server-addr: 127.0.0.1:8848
        # 所属命名空间id,用于区分开发、测试、生产
        namespace: def37ec7-353f-4a86-a77a-d27897e2429f
        # 设置为false可以只发现其他服务但不注册自身,用于本地代码调试
        register-enabled: false
  config:
    # 因为springboot 2.4版本以后默认关闭加载bootstrap.yml,所以只能通过此方式连接到nacos config
    import: nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension}

其中的关键点在于spring.config.import,由于nacos(2.1.0)目前仍未对springboot 2.4+版本做对应优化,只能通过手动拼接dataId的方式去获取配置。
spring.config.import后如果加上了optional:,则表示允许连接不成功时继续启动项目,例如:
spring.config.import: optional:nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension}

用到的相关文档

Nacos Config 2.4.x Example
Spring Cloud Alibaba Nacos Config
Spring Cloud Alibaba 2021.0.1.0 升级指南
Config First Bootstrap


版权声明:本文为u012760435原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。