nacos配置动态刷新及监听到变化触发一些方法

这篇具有很好参考价值的文章主要介绍了nacos配置动态刷新及监听到变化触发一些方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

介绍

在使用spring 时,动态更新配置是常见的,属性值更新,但是需要开启支持刷新功能,一个是spring.cloud.nacos.config.isRefreshEnabled=true; 这个值一般是默认的,可以在nacosConfigProperties这个类中看到。还要在扩展配置中开启refresh = true

spring
    cloud:
      nacos:
        config:
          server-addr: ${nacos-ip}
          extension-configs[0]:
            data-id: ${spring.application.name}.yml
            group: base
        # 这个地方必须开启,否则不会自动刷新
            refresh: true

2 使用

2.1 新建配置类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "apply.demo")
public class DemoConfig {

    /**
     * 配置信息
     */
    private String config;
}

2.2 新建测试访问类


import com.purgeteam.dynamic.config.starter.event.ActionConfigEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
@RequestMapping("/api/test2")
public class Test2Controller {//

    @Autowired
    private DemoConfig demoConfig;



    @GetMapping(value = "dd")
    public String test4(String params){

        log.info("dsds" + params);

        System.out.println(demoConfig.getConfig());
        System.out.println(SpringUtil.getApplicationContext().getBean("testController"));
        // 保存数据
        return demoConfig.getConfig();
    }

}

2.3 yml配置

apply:
  demo:
    config: 2225dssww

测试结果: 配置中心值改变,对应的属性值也改变

------这里好像没用加@RefreshScope注解

3. 监听到变化触发方法

在监听到配置值变化后,需要触发一些方法,需要实现ApplicationListener<T> 接口,重写onApplicationEvent方法

3.1 触发代码


import com.purgeteam.dynamic.config.starter.event.ActionConfigEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
@RequestMapping("/api/test2")
public class Test2Controller implements ApplicationListener<ActionConfigEvent> {//

    @Autowired
    private DemoConfig demoConfig;



    @GetMapping(value = "dd")
    public String test4(String params){

        log.info("dsds" + params);

        System.out.println(demoConfig.getConfig());
        System.out.println(SpringUtil.getApplicationContext().getBean("testController"));
        // 保存数据
        return demoConfig.getConfig();
    }

// 这个方法会在属性变化后调用,这里可以根据某个值变化去处理其他逻辑
    @Override
    public void onApplicationEvent(ActionConfigEvent actionConfigEvent) {
// 获取变化的key
        Map<String, HashMap> propertyMap = actionConfigEvent.getPropertyMap();
// 取出变化的key的map
        HashMap hashMap = propertyMap.get("spring.profiles1.active1");
// 变化后的值
        Object after = hashMap.get("after");
// 变化前的值
        Object after = hashMap.get("before");
// 打印属性值
        log.info("====env========={}",this.demoConfig.getConfig());
    }
}

4. 执行流程分析

处理属性变化绑定值类org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder#onApplicationEvent

自己可以打断点,看方法走向。

获取服务端配置最后是一个string,在com.alibaba.nacos.client.config.impl.ClientWorker.LongPollingRunnable#run这个方法中

String[] ct = ClientWorker.this.getServerConfig(dataId, group, tenant, 3000L);

4.1 服务启动注册配置监听

com.alibaba.cloud.nacos.refresh.NacosContextRefresher#onApplicationEvent这里会调用注册方法com.alibaba.cloud.nacos.refresh.NacosContextRefresher#registerNacosListenersForApplications

// 注册监听方法
private void registerNacosListenersForApplications() {
// 全局开启刷新,默认是true
        if (isRefreshEnabled()) {
            for (NacosPropertySource propertySource : NacosPropertySourceRepository
                    .getAll()) {
            // 判断单个配置文件是否支持刷新,就是refresh = true,开启了就会注册监听,有变化就会及时通知
                if (!propertySource.isRefreshable()) {
                    continue;
                }
                String dataId = propertySource.getDataId();
                // 调用注册方法
                registerNacosListener(propertySource.getGroup(), dataId);
            }
        }
    }
private void registerNacosListener(final String groupKey, final String dataKey) {
        String key = NacosPropertySourceRepository.getMapKey(dataKey, groupKey);
        // 创建监听
        Listener listener = listenerMap.computeIfAbsent(key,
                lst -> new AbstractSharedListener() {
                    @Override
                    public void innerReceive(String dataId, String group,
                            String configInfo) {
                        refreshCountIncrement();
                        nacosRefreshHistory.addRefreshRecord(dataId, group, configInfo);
                        // todo feature: support single refresh for listening
                        applicationContext.publishEvent(
                                new RefreshEvent(this, null, "Refresh Nacos config"));
                        if (log.isDebugEnabled()) {
                            log.debug(String.format(
                                    "Refresh Nacos config group=%s,dataId=%s,configInfo=%s",
                                    group, dataId, configInfo));
                        }
                    }
                });
        try {

        // 这里是最重要的,将监听添加到,config里,注册上
            configService.addListener(dataKey, groupKey, listener);
        }
        catch (NacosException e) {
            log.warn(String.format(
                    "register fail for nacos listener ,dataId=[%s],group=[%s]", dataKey,
                    groupKey), e);
        }
    }

4.2 配置改变刷新配置属性

调用到org.springframework.cloud.context.refresh.ContextRefresher#refreshEnvironment


// 返回变化的key
public synchronized Set<String> refreshEnvironment() {
// 以前的配置的值
        Map<String, Object> before = this.extract(this.context.getEnvironment().getPropertySources());
        this.addConfigFilesToEnvironment();
// 改变后的key
        Set<String> keys = this.changes(before, this.extract(this.context.getEnvironment().getPropertySources())).keySet();

// 发布环境变化时间,spring内部事件
        this.context.publishEvent(new EnvironmentChangeEvent(this.context, keys));
// 返回变化的key
        return keys;
    }

求出以前和现在变化的key

private Map<String, Object> changes(Map<String, Object> before, Map<String, Object> after) {
        Map<String, Object> result = new HashMap();
        Iterator var4 = before.keySet().iterator();

        String key;
        while(var4.hasNext()) {
            key = (String)var4.next();
            if (!after.containsKey(key)) {
                result.put(key, (Object)null);
            } else if (!this.equal(before.get(key), after.get(key))) {
                result.put(key, after.get(key));
            }
        }

        var4 = after.keySet().iterator();

        while(var4.hasNext()) {
            key = (String)var4.next();
            if (!before.containsKey(key)) {
                result.put(key, after.get(key));
            }
        }

        return result;
    }

环境变化事件处理

org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder#onApplicationEvent

public void onApplicationEvent(EnvironmentChangeEvent event) {
        if (this.applicationContext.equals(event.getSource()) || event.getKeys().equals(event.getSource())) {
// 重新绑定值
            this.rebind();
        }

    }

这里会看到需要绑定的配置类

nacos配置动态刷新及监听到变化触发一些方法

开始绑定

nacos配置动态刷新及监听到变化触发一些方法

这里绑定值后,虽然经过了销毁和初始化,发现,地址没有变,里面的值变了

刷新后还会调用这个方法org.springframework.cloud.context.refresh.ContextRefresher#refresh

发布一个RefreshScopeRefreshedEvent事件

com.purgeteam.dynamic.config.starter.event.DynamicConfigApplicationListener#onApplicationEvent

public void onApplicationEvent(RefreshEvent event) {
        ConfigurableEnvironment beforeEnv = (ConfigurableEnvironment)this.context.getEnvironment();
        MutablePropertySources propertySources = beforeEnv.getPropertySources();
        MutablePropertySources beforeSources = new MutablePropertySources(propertySources);
        Set<String> refresh = this.refresh.refresh();
        Map<String, HashMap> contrast = this.propertyUtil.contrast(beforeSources, propertySources);

// 发布一个配置变化事件
        this.context.publishEvent(new ActionConfigEvent(this, "Refresh config", contrast));
        log.info("[ActionApplicationListener] The update is successful {}", refresh);
    }

调用到自己的方法

public void onApplicationEvent(ActionConfigEvent actionConfigEvent) {
        Map<String, HashMap> propertyMap = actionConfigEvent.getPropertyMap();
        HashMap hashMap = propertyMap.get("spring.profiles1.active1");
        Object after = hashMap.get("after");
// 触发其他逻辑
        log.info("====env========={}",this.demoConfig.getConfig());
    }

5. 总结

这里主要介绍了使用。

如果属性刷新需要处理逻辑,就需要实现ApplicationListener接口

需要注意配置是怎么注册监听的。文章来源地址https://www.toymoban.com/news/detail-440728.html

到了这里,关于nacos配置动态刷新及监听到变化触发一些方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • nacos 监听配置文件变动(自动刷新),监听服务变动(权重、元数据等),手动推送服务

    对于启动项目时可以检测的配置文件,修改配置文件时也可进入监听,对于服务监听时,项目启动时注册进nacos可以监听,修改服务时关闭服务时都可以监听,也可以手动推送服务到nacos上。 nacos上的配置文件名称为:服务名称-dev.yaml bootstrap.yml

    2024年02月15日
    浏览(30)
  • springboot - 实现动态刷新配置

    这里不加@Component,是因为: FilePropertiesSource filePropertiesSource = new FilePropertiesSource(); // 属性源是按照添加的顺序进行合并的,后添加的属性源中的属性会覆盖前面添加的属性源中的同名属性。 // 因此,为了确保我们自定义的属性源中的属性优先级最高,我们需要将它添加到属

    2024年02月01日
    浏览(25)
  • springboot配置项动态刷新

    springboot 配置文件一般以yaml方式保存,除了系统配置项如spring、server等外,还有我们自定义的配置项,方便系统启动时自动注入。 自定义的配置项一般是动态配置项,在系统运行过程中,可能需要在线修改,来实现自定义的配置项不停服更新,也就是类似于spring-cloud-starter

    2024年01月22日
    浏览(36)
  • gateway+nacos动态路由配置

    spring cloud微服务场景下,需要使用到路由转发组。本文将从3个方面介绍路由配置: 简单的场景 通过nacos动态路由配置 常用配置属性 我使用的版本: 各组件版本尽量与这个一致,版本参考: https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 配置gateway路由前

    2024年02月09日
    浏览(32)
  • java动态获取nacos配置文件

    前言: 在不启动服务的情况下,修改nacos配置文件,可以动态的获取到配置文件的信息,实现动态刷新的效果。 1、依赖jar包 2、相关代码 3、注意事项 1、注解@RefreshScope为动态刷新,如果需要检验是否成功。可以写一个Junit测试,while(true)循环打印获取到的信息。我们修改naco

    2024年02月09日
    浏览(28)
  • Nacos SpringBoot 动态配置 不生效

    写法参考了 官方文档 Nacos Spring 快速开始 Nacos Spring Boot 快速开始 maven 启动类上添加对应的注解 controller验证 以上写法都没问题 用nacos的接口查看修改配置 浏览器访问地址 127.0.0.1:8848/nacos/v1/cs/configs?dataId=xxx-dynamic-configuration.ymlgroup=DEFAULT_GROUPtenant=xxx-xx-xxx-xx-xxxx 可以看到都是每

    2024年02月11日
    浏览(32)
  • springcloud3 bus+springconfig 实现配置文件的动态刷新(了解)

    spring cloud bus是用来将分布式系统的节 点与轻量级消息系统链接起来的框架。 它整合了java的事件处理机制和消息中间件的功能。其中目前支持RabbitMQ和kafka 简介: bus实现多个服务的配置文件动态刷新。 1.2.1 rabbitmq的配置  1.2.2 工程结构  1.2.2 实现方式 1.利用消息纵向触发一个

    2024年02月13日
    浏览(30)
  • 排查一次nacos动态配置不生效

    一、问题描述 新需求需要使用到nacos动态配置,但是开发完成之后联调过程中发现动态配置没有生效。 二、问题排查 首先在本地测试,发现启动服务后修改nacos配置确实不生效,在查看启动日志时发现服务启动时打印了下面这样的日志。这里是在配置nacos的监听,在A服务的启

    2023年04月11日
    浏览(34)
  • 使用Nacos配置中心动态管理Spring Boot应用配置

    🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐 🌊 《100天精通Golang(基础入门篇)》学会Golang语言

    2024年02月12日
    浏览(48)
  • 【Java项目】使用Nacos实现动态线程池技术以及Nacos配置文件更新监听事件

    真诚的希望能给我项目一个stars!!! 项目源码 项目视频演示 线程池(Thread Pool)是一种基于池化思想管理线程的工具,经常出现在多线程服务器中,如Tomcat。 线程过多会带来额外的开销,其中包括创建销毁线程的开销、调度线程的开销等等,同时也降低了计算机的整体性

    2024年02月09日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包