当我们把nacos服务端启动起来,项目中也集成好之后,兴高采烈的启动项目准备试一下,发现在nacos中修改配置之后发现项目中的配置竟然没有刷新,然后开始怀疑是不是自己那里配置的不对、那个注解没有写、nacos版本是不是和springboot不兼容,然后一通修改,最后发现还是不行,最后开始怀疑人生。
下面两个场景可能会帮到你

1.没有开启nacos的自动刷新

springboot集成nacos的时候,需要在项目的配置文件里加入如下配置

nacos:
  config:
    bootstrap:
      enable: true
    # nacos服务ip和端口
    server-addr: 127.0.0.1:8848
    data-id: test
    group: local
    username: nacos
    password: nacos
    type: yaml
    # 开启nacos自动刷新,如果这个配置没有或者为false会导致配置不能自动刷新
    auto-refresh: true
    # 允许nacos服务端向本地同步配置
    enable-remote-sync-config: true

并且在配置属性上使用@NacosValue注解并且配置注解的autoRefreshed的值为true(默认为false,不会自动刷新),两个配置缺一不可;如果你使用的是spring的@Value注解,只能获取到配置,但不能自动刷新配置。
到这里借本就可以解决99%的问题了,剩下的1%的问题接着往下看

2.项目中集成了ulisesbocchio或者类似的插件,对配置进行加密

如果不想看细节,只想解决问题,可以直接把项目中ulisesbocchio或者类似的插件移除掉,然后把加密的配置变成明文放到nacos中就好了。
------------------------下面进行问题定位------------------------
在nacos中修改配置后,会自动通知给客户端,客户端在收到通知变更的请求后,经过一系列的前戏会执行到
com.alibaba.nacos.client.config.impl.CacheData#safeNotifyListener这个方法里,源码如下我们在这个方法的第一行打一个断点追踪一下执行链路;

<dependency>
        <groupId>com.github.ulisesbocchio</groupId>
        <artifactId>jasypt-spring-boot-starter</artifactId>
        <version>${jasypt-spring-boot-starter.version}</version>
    </dependency>
private void safeNotifyListener(final String dataId, final String group, final String content, final String type,
            final String md5, final String encryptedDataKey, final ManagerListenerWrap listenerWrap) {
        final Listener listener = listenerWrap.listener;
        if (listenerWrap.inNotifying) {
            LOGGER.warn(
                    "[{}] [notify-currentSkip] dataId={}, group={}, md5={}, listener={}, listener is not finish yet,will try next time.",
                    name, dataId, group, md5, listener);
            return;
        }
        //这里创建了一个线程,异步的修改配置,保证保证本次配置变更请求能够快速响应
        Runnable job = new Runnable() {
            @Override
            public void run() {
                long start = System.currentTimeMillis();
                ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader();
                ClassLoader appClassLoader = listener.getClass().getClassLoader();
                try {
                    if (listener instanceof AbstractSharedListener) {
                        AbstractSharedListener adapter = (AbstractSharedListener) listener;
                        adapter.fillContext(dataId, group);
                        LOGGER.info("[{}] [notify-context] dataId={}, group={}, md5={}", name, dataId, group, md5);
                    }
                    // Before executing the callback, set the thread classloader to the classloader of
                    // the specific webapp to avoid exceptions or misuses when calling the spi interface in
                    // the callback method (this problem occurs only in multi-application deployment).
                    Thread.currentThread().setContextClassLoader(appClassLoader);
                    
                    ConfigResponse cr = new ConfigResponse();
                    cr.setDataId(dataId);
                    cr.setGroup(group);
                    cr.setContent(content);
                    cr.setEncryptedDataKey(encryptedDataKey);
                    configFilterChainManager.doFilter(null, cr);
                    String contentTmp = cr.getContent();
                    listenerWrap.inNotifying = true;
                    // contentTmp这个变量里存储了最新的全量配置,也是我们这次源码追踪的重点,看看是如何自动刷新配置的
                    listener.receiveConfigInfo(contentTmp);
                    // compare lastContent and content
                    if (listener instanceof AbstractConfigChangeListener) {
                        Map data = ConfigChangeHandler.getInstance()
                                .parseChangeData(listenerWrap.lastContent, content, type);
                        ConfigChangeEvent event = new ConfigChangeEvent(data);
                        ((AbstractConfigChangeListener) listener).receiveConfigChange(event);
                        listenerWrap.lastContent = content;
                    }
                    
                    listenerWrap.lastCallMd5 = md5;
                    LOGGER.info("[{}] [notify-ok] dataId={}, group={}, md5={}, listener={} ,cost={} millis.", name,
                            dataId, group, md5, listener, (System.currentTimeMillis() - start));
                } catch (NacosException ex) {
                    LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} errCode={} errMsg={}",
                            name, dataId, group, md5, listener, ex.getErrCode(), ex.getErrMsg());
                } catch (Throwable t) {
                    LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} tx={}", name, dataId,
                            group, md5, listener, t.getCause());
                } finally {
                    listenerWrap.inNotifying = false;
                    Thread.currentThread().setContextClassLoader(myClassLoader);
                }
            }
        };
        
        final long startNotify = System.currentTimeMillis();
        try {
            if (null != listener.getExecutor()) {
                //将上面创建的线程放到线程池里执行
                listener.getExecutor().execute(job);
            } else {
                try {
                    INTERNAL_NOTIFIER.submit(job);
                } catch (RejectedExecutionException rejectedExecutionException) {
                    LOGGER.warn(
                            "[{}] [notify-blocked] dataId={}, group={}, md5={}, listener={}, no available internal notifier,will sync notifier ",
                            name, dataId, group, md5, listener);
                    job.run();
                } catch (Throwable throwable) {
                    LOGGER.error(
                            "[{}] [notify-blocked] dataId={}, group={}, md5={}, listener={}, submit internal async task fail,throwable= ",
                            name, dataId, group, md5, listener, throwable);
                    job.run();
                }
            }
        } catch (Throwable t) {
            LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} throwable={}", name, dataId,
                    group, md5, listener, t.getCause());
        }
        final long finishNotify = System.currentTimeMillis();
        LOGGER.info("[{}] [notify-listener] time cost={}ms in ClientWorker, dataId={}, group={}, md5={}, listener={} ",
                name, (finishNotify - startNotify), dataId, group, md5, listener);
    }

由于篇幅问题,后面的我用图片展示,大家根据图片可以自行追踪

nacos改动java代码不刷新 nacos数据库配置不刷新_spring cloud

nacos改动java代码不刷新 nacos数据库配置不刷新_nacos改动java代码不刷新_02

nacos改动java代码不刷新 nacos数据库配置不刷新_java_03

nacos改动java代码不刷新 nacos数据库配置不刷新_spring cloud_04

nacos改动java代码不刷新 nacos数据库配置不刷新_nacos改动java代码不刷新_05

nacos改动java代码不刷新 nacos数据库配置不刷新_spring cloud_06

nacos改动java代码不刷新 nacos数据库配置不刷新_spring_07

nacos改动java代码不刷新 nacos数据库配置不刷新_nacos改动java代码不刷新_08

nacos改动java代码不刷新 nacos数据库配置不刷新_spring cloud_09

代码调试完成后,问题的根源也就找到了,接下来就是删除配置加密组件,修改为明文配置,启动项目,搞定收工。