• java后端:nacos 实现动态配置


    一、前言

    使用动态配置的原因: properties 和 yaml 是写到项目中的,好多时候有些配置需要修改,每次修改就要重新启动项目,不仅增加了系统的不稳定性,也大大提高了维护成本,非常麻烦,且耗费时间。
    使用动态配置,则可以避免这些麻烦,可以动态的修改配置,不需要重新启动项目。
    nacos配置中心,可以使得配置标准化、格式统一化,当配置信息发生变动时,修改实时生效,无需要重新重启服务器,就能够自动感知相应的变化,并将新的变化统一发送到相应程序上,快速响应变化。

    本次环境使用版本:NACOS1.4.2; spring-boot 2.3.9.RELEASE;nacos-config-spring-boot-starter 0.2.1

    二、在 nacos 上创建配置文件

    2.1 在默认命名空间中,创建一个配置文件

    在这里插入图片描述

    2.2 配置说明:

    • Data ID —— 用于项目读取名称,spring-nacos 动态配置命名规范为 :{prefix}-{spring.profiles.active}.{file-extension}
    • prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
    • spring.profiles.active 即为当前环境对应的 profile,就是环境的命名,比如 test 环境, dev 环境;spring.profiles.active 可以为空,为空着不区分环境信息,dataId 的拼接格式变成 {prefix}.{file-extension}。
    • file-exetension 为配置内容的数据格式,一般常用 properties 和 yaml 类型。
    说明:
    • 我这次修改的项目是网关,项目名称 :gateway(spring.application.name= gateway)
    • 没有使用环境配置
    • 所以 nacos 的配置文件为: {prefix}.{file-extension} 即 gateway.yml
    • 如果有配置环境的,可以为 {prefix}-{spring.profiles.active}.{file-extension} 即 gateway-dev.yml

    本次配置文件名称为 gateway.yml

    在这里插入图片描述
    注意: 项目启动时,nacos-config 会自动加载以下文件,故以下文件名称都可以作为默认动态配置的文件格式。

    • icp-gateway-dev.yml,icp-gateway.yml,icp-gateway,(说明,这三个文件,可以指定命名 nacos 分组)
    • common.yml (该文件为默认分组,DEFAULT_GROUP)

    添加测试使用的配置 nacosConfigDemmo: NAME1
    在这里插入图片描述

    说明: 本次配置项目,分组名称为 ICP_PLATFORM (注意:分组名称建议使用下划线 _ ,不建议使用 中横线 - ,中横线会有几率出现不能读取的问题,使用连接符请注意使用;分组名可以自定,如果要区分命名空间,需要到 nacos 命名空间 中新建 命名空间)

    2.3 发布并检查配置文件

    • 编辑完成之后,直接点击发布,会提示新建完成
      在这里插入图片描述
    • 点击确定,然后点击返回配置中心,在配置列表中能找到自己的配置文件,确保文件内容正确即可
      在这里插入图片描述
      至此,配置文件完成,接下来在项目中使用这个配置文件。

    三、 修改修改项目配置,动态读取配置文件

    3.1 添加 nacos 动态配置依赖

    在 pom.xml 文件中,添加依赖。

    <dependency>
        <groupId>com.alibaba.bootgroupId>
        <artifactId>nacos-config-spring-boot-starterartifactId>
        <version>0.2.1version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    修改项目配置文件,读取 nacos 中的配置内容

    # 指定启动端口
    server:
      port: 7200
    spring:
      application:
      # 指定服务名称
        name: gateway
      # 项目运行环境,可以搭配在 nacos 动态配置文件名上面,不同环境使用不同的动态配置
      profiles:
        active: dev
      cloud:
        nacos:
          config:
          	server-addr: 127.0.0.1:8848  #nacos 的注册地址
            file-extension: yml  #动态配置文件的 格式。就是 nacos 中的动态配置,这里是 yml
            group: ICP_PLATFORM  #nacos 动态配置的分组,要与 nacos 配置文件保持一致
    #        namespace:   #namespace 是nacos 的命名空间,我这儿是默认空间,就不配置了 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3.2 在 controller 与 service 中使用动态配置

    controller 代码:

    import com.insupro.search2.service.IIndexService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/api/demo")
    public class nacosConfigDemmo {
    
        @Autowired
        private DemoService demoService;
    
        @GetMapping("/name")
        public Object showDemoName(){
            return demoService.showDemoName();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    service 接口代码:

    public interface IIndexService {
    	Object showDemoName();
    }
    
    • 1
    • 2
    • 3

    service 实现代码:

    import com.insupro.search2.service.demoService;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.stereotype.Service;
    
    @Service
    // 注意,要自动刷新配置,需要 @RefreshScope 这个注解
    @RefreshScope
    public class demoServiceImpl implements demoService{
    
    	/**
    	* 使用在上面nacos 中添加的测试使用配置。
    	*/
        @Value("${nacosConfigDemmo}")
        private String demoName;
    
        @Override
        public Object showDemoName(){
            return demoName;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    运行,请求接口地址,得到响应值:
    postman 请求,第一次响应,值为 NAME2
    在这里插入图片描述
    修改 nacos 配置文件,将 nacosConfigDemmo: NAME1 改为 nacosConfigDemmo: NAME2 并发布
    在这里插入图片描述
    等待控制台打印: Refresh keys changed: [nacosConfigDemmo],则动态配置已经生效
    在这里插入图片描述
    再次请求,发现返回值已经改变:
    在这里插入图片描述
    请求结果,NAME1 已经变成 NAME2,项目不需要重启,动态配置已经生效。

    四、 动态配置网关的使用

    4.1 导入配置,网关不进行权限校验的路径

    获取配置文件,生成 bean

    import lombok.Getter;
    import lombok.Setter;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    
    // 自动刷新机制,需要 get 方法支撑
    @Setter
    @Getter
    // 获取配置文件
    @ConfigurationProperties(prefix = "security.ignore")
    // 开启自动刷新
    @RefreshScope
    public class SecurityProperties { 
        private PermitProperties ignore = new PermitProperties();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    配置文件实体类

    import lombok.Getter;
    import lombok.Setter;
    
    @Setter
    @Getter
    public class PermitProperties {
        /**
         * 设置不用认证的url
         */
        private String[] httpUrls = {};
        
        public String[] getUrls() {
            if (httpUrls == null || httpUrls.length == 0) {
                return new ArrayList<>();
            }
            List<String> list = new ArrayList<>();
            for (String url : httpUrls) {
                list.add(url);
            }
            return list.toArray(new String[list.size()]);
        }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    至此,导入自动配置完成,可以根据自己的业务代码进行网关的配置与使用。
    但是!!注意!! 如果在配置文件中调用配置,则需要在配置文件中使用 @RefreshScope 注解,用于刷新配置。因为配置文件在项目启动时便已经完成加载。

    例如:

    @Configuration
    public class ResourceServerConfiguration {
        @Autowired
        private SecurityProperties securityProperties;
     
        // 使用了 @Configuration 定义配置文件,并在配置类中使用 @Bean 装配 bean,此时如果在自动装配出没有使用 @RefreshScope 注解,则自动配置不会生效。
        @Bean
        @Autowired(required = false)
        @RefreshScope
        SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
            if (securityProperties.getIgnore().getUrls().length > 0) {
                authorizeExchange.pathMatchers(securityProperties.getIgnore().getUrls()).permitAll();
            }
            // TODO 余下自行业务代码 …………
            return http.build();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    博客系统项目详解
    国内AI大赛汇总
    flutter项目中常用第三方模块
    javascript 文本框中的数据丢失格式,导致没有换行,显示成一行,flask不显示本地图片问题
    力扣hot100——第2天:4寻找两个正序数组的中位数、5最长回文子串、10正则表达式匹配
    mongoose 搭建 http 服务 -- 编译
    Flink 窗口延迟数据处理 AllowedLateness
    【Educoder数据挖掘实训】插值填充法处理遗漏值
    【SSM直击大厂】最终章:SSM 整合
    汇舟问卷:想要挣钱?海外问卷调查不容错过!
  • 原文地址:https://blog.csdn.net/hongchen006/article/details/126586367