相关推荐recommended
Nacos:配置中心(三)
作者:mmseoamin日期:2023-12-13

目录

1.Nacos定位

2.Nacos的安装配置

3.整合Nacos

3.1.Nacos安装

3.2.Nacos登录

3.3.配置Nacos     

4.Nacos使用

4.1.引入 Maven 依赖

4.2.配置bootstrap.yml

4.3.Nacos配置类

4.4.启用Nacos服务

4.5.测试获取配置

5.加载多个配置文件

datasource-dev.yaml

mybatis-plus-dev.yaml

本地文件bootstrap.yml

Contro代码

测试结果

总结

6.异常处理

鸣谢


1.Nacos定位

微服务架构下关于配置文件的一些问题:

        配置文件相对分散。在一个微服务架构下,配置文件会随着微服务的增多变的越来越多,而且分散

在各个微服务中,不好统一配置和管理。

        配置文件无法区分环境。微服务项目可能会有多个环境,例如:测试环境、预发布环境、生产环

境。每一个环境所使用的配置理论上都是不同的,一旦需要修改,就需要我们去各个微服务下手动

维护,这比较困难。

        配置文件无法实时更新。我们修改了配置文件之后,必须重新启动微服务才能使配置生效,这对一

个正在运行的项目来说是非常不友好的。

基于上面这些问题,我们就需要配置中心的加入来解决这些问题。

配置中心的思路是:

  • 首先把项目中各种配置全部都放到一个集中的地方进行统一管理,并提供一套标准的接口。
  • 当各个服务需要获取配置的时候,就来配置中心的接口拉取自己的配置。
  • 当配置中心中的各种参数有更新的时候,也能通知到各个服务实时的过来同步最新的信息,使之动态更新。

    总结:

            服务管理平台:服务注册、配置和路由

            配置管理:统一的配置管理

    2.Nacos的安装配置

    Nacos的学习资源主要有以下两个

            Nacos官网: Nacos官网

            Nacos GitHub: NacosGitHub

            快速下载 nacos 的地址 :快速下载地址

    3.整合Nacos

    本项目使用版本一览,测试两个版本都ok

    Spring BootSpring CloudSpring Cloud AlibabaNocosJDK
    2.7.72021.0.52021.0.5.02.2.9.RELEASE1.8

    2.3.12.RELEASE

    2.2.9.RELEASE

    1.8

    注意:SpringBoot3.0开始不支持jdk8

    3.1.Nacos安装

    参考博客:Nacos安装(二)

    3.2.Nacos登录

    单机模式启动Nocos服务后,访问登录

    地址:http://127.0.0.1:8848

    用户名/密码:nacos/nocos

    Nacos:配置中心(三),第1张

    3.3.配置Nacos     

    1)配置中心简介

    • 命名空间Namespace:用来区分环境
      • 开发(dev)、测试(test)、生产(prod):利用命名空间来做环境隔离
    • Data ID: 用来区分配置,可以理解成对应我们的一个微服务
      • 例如:数据空配置,redis配置,kafka配置。
      • 命名规则:application.name + profiles.active + file-extension。
      • 如果bootstrap.yml文件中没有配置profiles.active + file-extension,我们只需要用服务名命名即可。
      • Group:用来区分不同的应用,默认DEFAULT_GROUP,如果在bootstrap.yml配置了profiles.active,这里填写profiles.active的值即可。
      • 配置格式:和项目对应

        2)创建命名空间

        如果想指定不同开发环境配置,如开发环境,测试环境等,我们就需要配置我们刚刚在上面讲的namespace。创建命名空间如下图所示:

        Nacos:配置中心(三),第2张

        命名空间ID:测试环境、生产环境

        描述:对环境的描述

        Nacos:配置中心(三),第3张

         创建命名空间后,我们就可以在配置列表中看到我们创建的命名空间

        Nacos:配置中心(三),第4张

        3)创建配置文件

        选择对应的命名空间,点击右边加号创建配置文件 

        Nacos:配置中心(三),第5张

        dataId 的完整格式如下:

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

        prefix:默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置

        spring.profiles.active:即为当前环境对应的 profile。 注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变

        file-exetension:为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。

        比如说我们现在要获取应用名称为nacos-config-client的应用在dev环境下的yaml配置,dataid如下:

        nacos-config-client-dev.yaml

        4.Nacos使用

                使用nacos作为配置中心,Nacos读取的是bootstrap.yml,而我们项目中的配置文件名称是application.properties/application.yml,所以我们要修改我们项目中的配置文件名为bootstrap.yml。

        4.1.引入 Maven 依赖

        首先,我们还是要引入 Maven 依赖,在maven仓库使用最新版本:

        Maven Repository: nacos

        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
            2.2.9.RELEASE
        
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-config
            2.2.9.RELEASE
        

        注意:注册中心和配置中心的依赖版本要根据 SpringBoot 版本来选择。

        具体版本对应关系;版本说明 · alibaba/spring-cloud-alibaba Wiki (github.com) 

        Nacos:配置中心(三),第6张

        4.2.配置bootstrap.yml

        在微服务resources中创建bootstrap.yml文件,添加如下nacos配置信息:

        spring:
          application:
            name: nacos-test
          profiles:
            #指定启动环境
            active: dev
          cloud:
            nacos:
              discovery:
                # Nacos服务注册中心地址
                server-addr: 127.0.0.1:8848
                # 分组,不同分组之间不能调用,用于微服务之间的隔离
                group: DEFAULT_GROUP
                # 生产环境
                namespace: 534c904d-7f24-4086-acbd-daf628cb1446
              config:
                # 是否开启配置中心 默认true
                enabled: true
                # 指定Nacos配置中心的地址
                server-addr: 127.0.0.1:8848
                # 区分环境:开发环境、测试环境、预发布环境、⽣产环境
                namespace: 91d34e57-55b0-4182-b881-ab0b5aefabe9
                # 区分不同应⽤:同⼀个环境内,不同应⽤的配置,通过group来区分。
                group: ${spring.profiles.active}
                #指定yaml格式的配置 默认properties
                file-extension: yaml
                # 自动刷新配置文件,默认true
                refresh-enabled: true
                # Nacos 认证用户
                username: nacos
                # Nacos 认证密码
                password: nacos
                # 配置文件prefix
                prefix: ${spring.application.name}
        

        4.3.Nacos配置类

                增加一个 Nacos 的配置文件,通过这个类可以拉取nacos中配置:

        import com.alibaba.cloud.nacos.NacosConfigProperties;
        import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
        import com.alibaba.nacos.api.exception.NacosException;
        import com.alibaba.nacos.api.naming.NamingService;
        import lombok.Data;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.beans.factory.annotation.Value;
        import org.springframework.cloud.context.config.annotation.RefreshScope;
        import org.springframework.stereotype.Component;
        import javax.annotation.PostConstruct;
        /**
         * @program: NacosConfig
         * @description: NacosConfig
         * @author: dyt
         * @create: 2022-07-29 16:39
         **/
        // 刷新配置
        @RefreshScope
        @Data
        @Component
        public class NacosConfig {
            @Value("${server.port}")
            private Integer serverPort;
            @Value("${spring.application.name}")
            private String applicationName;
        //    @NacosInjected
        //    private NamingService namingService;
            @Autowired
            NacosConfigProperties nacosConfigProperties;
            @Autowired
            NacosDiscoveryProperties nacosDiscoveryProperties;
          /**
           * 通过Naming服务注册实例到注册中心
           *
           * @throws NacosException
           */
           @PostConstruct
           public void registerInstance() throws NacosException {
            NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
            namingService.registerInstance(applicationName, "127.0.0.1", serverPort);
          }
        }
        
        • @NacosValue注解是Spring Cloud Alibaba Nacos提供的注解,用于获取Nacos配置中心的配置值。它可以自动监听配置变化并动态更新
        • @Value注解是Spring框架提供的注解,用于获取配置文件中的值,可以用于获取任意配置文件(如application.properties、application.yml)中的配置项。使用@Value注解时,需要指定配置项的完整路径,例如:@Value("${config.key}")。

        • 我这里NamingService 始终报空指针异常,只能自己初始化

         4.4.启用Nacos服务

                在Spring Boot的启动类上添加@EnableDiscoveryClient注解,启用Nacos的服务注册和发现功能。

        //启用Nacos作为服务发现的功能
        @EnableDiscoveryClient
        //引入了spring-cloud-starter-alibaba-nacos-discovery依赖时,默认情况下会自动启用Nacos的服务注册和发现功能
        @SpringBootApplication
        public class NacosTestApplication {
            public static void main(String[] args) {
                SpringApplication.run(NacosTestApplication.class, args);
            }
        }
        • 如果想要配置项的值自动刷新,仅在 @NacosPropertySource 加 autoRefreshed = true 是不够的,在 @NacosValue 上面也得加 autoRefreshed = true
        •  @EnableDiscoveryClient 注解,开启 Spring Cloud 的注册发现功能。不过从 Spring Cloud Edgware 版本开始,实际上已经不需要添加 @EnableDiscoveryClient 注解,只需要引入 Spring Cloud 注册发现组件,就会自动开启注册发现的功能。例如说,我们这里已经引入了 spring-cloud-starter-alibaba-nacos-discovery 依赖,就不用再添加 @EnableDiscoveryClient 注解了

        4.5.测试获取配置

        最后我们写一个模拟获取配置参数的 Controller 类👇

        import com.dyt.nacos.config.NacosConfig;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
        import javax.annotation.Resource;
        @RestController
        @RequestMapping("/nacos")
        public class NacosController {
            @Resource
            private NacosConfig nacosConfig;
            /**
             * 获取配置中心配置
             * @return
             */
            @RequestMapping("/getConfig")
            public String getConfig(){
                return nacosConfig.getMaxThreads()+nacosConfig.getCommon()+nacosConfig.getTest();
            }
        }

        5.加载多个配置文件

        • Nacos在配置路径spring.cloud.nacos.config.extension-config下,允许我们指定⼀个或多个额外配置。

        • Nacos在配置路径spring.cloud.nacos.config.shared-configs下,允许我们指定⼀个或多个共享配置。

        • 上述两类配置都⽀持三个属性:data-id、group(默认为字符串DEFAULT_GROUP)、refresh(默认为true)。

          datasource-dev.yaml

          #mysql和阿里druid配置
          spring:
            datasource:
              dynamic:
                primary: oracle-db #设置默认的数据源或者数据源组
                datasource:
                  oracle-db:
                    type: com.alibaba.druid.pool.DruidDataSource
                    driver-class-name: oracle.jdbc.OracleDriver
                    url: jdbc:oracle:thin:@192.168.5.100:1521:kylwspwh
                    username: root
                    password: MsI1#11OI1#1sW
                  mysql-adb:
                    type: com.alibaba.druid.pool.DruidDataSource
                    driver-class-name: com.mysql.jdbc.Driver
                    url: jdbc:mysql://192.168.5.22:3306/ordercenter?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
                    username: dzkp
                    password: H2!b1t#ub1_1n

          mybatis-plus-dev.yaml

          # mybatis-plus相关配置
          mybatis-plus:
            configuration:
              #开启sql日志
          #    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
              # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
              map-underscore-to-camel-case: true
              # 解决oracle更新数据为null时无法转换报错,mysql不会出现此情况
              jdbc-type-for-null: 'null'
            #实体类所在包
            type-aliases-package: com.batchUtil.model,com.batchUtil.bxp.model
            # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
            mapper-locations: classpath:mapper/*.xml

          本地文件bootstrap.yml

          application.yml作用域在于当前应用有效,bootstrap.yml系统级别的配置有效(一般采用远程配置的时候才会用到)。

          因此,将项目中原来的application.yml、application-dev.yml对应改成bootstrap.yml、bootstrap-dev.yml 。

           在应用程序的bootstrap.yml里的config节点下增加配置 extension-configs,表明额外配置文件:

          spring:
            application:
              name: nacos-test
            profiles:
              #指定启动环境
              active: dev
            cloud:
              nacos:
                discovery:
                  # Nacos服务注册中心地址
                  server-addr: 127.0.0.1:8848
                  # 分组,不同分组之间不能调用,用于微服务之间的隔离
                  group: ${spring.profiles.active}
                  # 生产环境
                  namespace: ${nacos.client.namespace}
                config:
                  # 是否开启配置中心 默认true
                  enabled: true
                  # 指定Nacos配置中心的地址
                  server-addr: 127.0.0.1:8848
                  # 区分环境:开发环境、测试环境、预发布环境、⽣产环境
                  namespace: 91d34e57-55b0-4182-b881-ab0b5aefabe9
                  # 区分不同应⽤:同⼀个环境内,不同应⽤的配置,通过group来区分。
                  group: ${spring.profiles.active}
                  # 配置文件的格式:指定yaml格式,配置 默认properties
                  file-extension: yaml
                  # 自动刷新配置文件,默认true
                  refresh-enabled: true
                  # Nacos 认证用户
                  username: nacos
                  # Nacos 认证密码
                  password: nacos
                  # 配置文件prefix
                  prefix: ${spring.application.name}
                  #共享配置文件:支持多个共享Data Id的配置,优先级小于extension-configs,自定义 Data Id 配置 属性是个集合,
                  # 内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh
                  # 用于共享的配置文件
                  shared-configs:
                    - data-id: datasource-${spring.profiles.active}.yaml
                      group: ${spring.profiles.active}
                      refresh: true
                  # 扩展配置文件:支持多个扩展Data Id的配置,优先级大于shared-configs,自定义 Data Id 配置 属性是个集合,
                    - data-id: mybatis-plus-${spring.profiles.active}.yaml
                      group: ${spring.profiles.active}
                      refresh: true
                  # 常规配置文件
                  # 优先级大于 shared-configs,在 shared-configs 之后加载
                  extension-configs:
                    - data-id: datasource-${spring.profiles.active}.yaml
                      group: ${spring.profiles.active}
                      refresh: true
                    - data-id: mybatis-plus-${spring.profiles.active}.yaml
                      group: ${spring.profiles.active}
                      refresh: true
          

          Contro代码

          import com.alibaba.cloud.nacos.NacosConfigProperties;
          import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
          import com.alibaba.nacos.api.exception.NacosException;
          import com.alibaba.nacos.api.naming.NamingService;
          import lombok.Data;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.beans.factory.annotation.Value;
          import org.springframework.cloud.context.config.annotation.RefreshScope;
          import org.springframework.stereotype.Component;
          import javax.annotation.PostConstruct;
          /**
           * @program: NacosConfig
           * @description: NacosConfig
           * @author: dyt
           * @create: 2022-07-29 16:39
           **/
          // 刷新配置
          @RefreshScope
          @Data
          @Component
          public class NacosConfig {
              @Value("${server.port}")
              private Integer serverPort;
              @Value("${spring.application.name}")
              private String applicationName;
          /*
              @NacosInjected
              private NamingService namingService;*/
              @Value("${spring.datasource.dynamic.primary}")
              private String primary;
              @Autowired
              NacosConfigProperties nacosConfigProperties;
              @Autowired
              NacosDiscoveryProperties nacosDiscoveryProperties;
            /**
             * 通过Naming服务注册实例到注册中心
             *
             * @throws NacosException
             */
            @PostConstruct
            public void registerInstance() throws NacosException {
              NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
              namingService.registerInstance(applicationName, "127.0.0.1", serverPort);
            }
          }
          
          import com.dyt.nacos.config.NacosConfig;
          import org.springframework.web.bind.annotation.RequestMapping;
          import org.springframework.web.bind.annotation.RestController;
          import javax.annotation.Resource;
          @RestController
          @RequestMapping("/nacos")
          public class NacosController {
              @Resource
              private NacosConfig nacosConfig;
            /**
               * 获取配置中心默认数据源名称
               *
               * @return
               */
              @RequestMapping("/primary")
              public String getPrimary(){
                  return nacosConfig.getPrimary();
              }
          }

          测试结果

          Nacos:配置中心(三),第7张

          总结

          关于优先级

          1)对同种配置,排在后⾯的相同配置,将覆盖排在前⾯的同名配置。

          2)不同种类配置之间,优先级按顺序如下:主配置 > 扩展配置(extension-configs) > 共享配置(shared-configs)

          上面的demo已经演示Nacos共享配置的两种实现方式,两种方式针对不同的场景,总结如下:

          shared-dataids方式:

                  适合于共享配置文件与项目默认配置文件处于相同Group时,直接两条命令就可以搞定
          优点:配置方便
          缺点:只能在同一Group中
          ext-config方式:

                  它可以由开发者自定义要读取的共享配置文件的DataId、Group、refresh属性,这样刚好解决了shared-dataids存在的局限性。
          优点:可以与shared-dataids方案结合使用,用户自定义配置。灵活性强
          缺点:配置容易出错,要熟悉YAML语法

          6.异常处理

          搭建过程中遇到控制针异常,NamingService使用初始化为null,只能寻求其他方式

          1)空指针:通过Naming服务注册实例到注册中心NamingService

          // 刷新配置
          @RefreshScope
          @Data
          @Component
          public class NacosConfig {
              @Value("${server.port}")
              private Integer serverPort;
              @Value("${spring.application.name}")
              private String applicationName;
              @Autowired
              NacosConfigProperties nacosConfigProperties;
              @Autowired
              NacosDiscoveryProperties nacosDiscoveryProperties;
            /**
             * 通过Naming服务注册实例到注册中心
             *
             * @throws NacosException
             */
            @PostConstruct
            public void registerInstance() throws NacosException {
                
              NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
              
              namingService.registerInstance(applicationName, "127.0.0.1", serverPort);
            }
          }

          鸣谢

          [1].https://blog.csdn.net/weixin_63719049/article/details/128263045

          [2].https://www.jianshu.com/p/8715072d3f4c

          [3].https://www.jianshu.com/p/df87a308edff

          [4].https://juejin.cn/post/6953045578095788068

          [5].https://juejin.cn/post/7152438783269421093

          [6].https://blog.csdn.net/qq_33619378/article/details/98972790

          [7].https://blog.csdn.net/ysj1241267542/article/details/112562611

          [8].https://blog.csdn.net/z69183787/article/details/109467120

          [9].https://blog.csdn.net/weixin_42329623/article/details/131018680