Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nacos Config配置监听比Spring的Environment要快,导致获取的配置还是旧的。 #3920

Closed
youngledo opened this issue Dec 10, 2024 · 10 comments
Labels
area/nacos spring cloud alibaba nacos kind/question

Comments

@youngledo
Copy link

Which Component

  • Nacos Config
  • 版本:2021.0.1.0

Describe the bug
由于业务场景需要监听nacos的配置改变,做了以下代码处理:

    private void addListener(ConfigService configService, Executor executor, NacosConfigProperties.Config config) {
        String dataId = config.getDataId();
        configService.addListener(dataId, config.getGroup(), new Listener() {
            @Override
            public Executor getExecutor() {
                return executor;
            }

            @SneakyThrows
            @Override
            public void receiveConfigInfo(String configInfo) {
                ConfigListener.ChangedEvent event = new ConfigListener.ChangedEvent(dataId, configInfo);
                eventPublisher.publishEvent(event);
                System.out.println("这是nacos监听器:" + configInfo);
                listenerOptional.ifPresent(listener -> listener.onChanged(event));
            }
        });
    }

当配置修改后,通过Spring的Environment获取配置,发现这时候拿到的配置还是旧的,代码如下:

    private final Environment environment;

    @SneakyThrows
    @Override
    public void onChanged(ChangedEvent event) {
        ApaasApplicationProperties applicationProperties = Binder.get(environment).bindOrCreate(
                "apaas", Bindable.of(ApaasApplicationProperties.class)
        );
        System.out.println(JSON.toJSONString(applicationProperties));
    }

但如果我在监听代码中睡眠一定时间(如2秒),则能正常拿到最新的配置,睡眠代码如下:
image

这是我通过日志观察到的效果:
Snipaste_2024-12-10_17-06-10

Expected behavior
在监听到nacos配置有变化时,通过Spring的Environment能拿到最新的配置。

@yuluo-yx yuluo-yx added kind/question area/nacos spring cloud alibaba nacos labels Dec 10, 2024
@shiyiyue1102
Copy link
Contributor

从机制上,nacos的配置是最终一致性,nacos多个监听器之间并没有依赖关系,nacos保证的是通过监听器receiveConfigInfo接收到的是最新的配置,但不保证其他的监听器(更新Spring Enviroment)已经接受到了最新的结果

@youngledo
Copy link
Author

这个机制是否有可能做些调整,毕竟nacos的配置最终还是要刷新到Spring Environment中?

@shiyiyue1102
Copy link
Contributor

Environment

这个机制不好调整,现在你遇到的问题本质上是使用方式不对

@youngledo
Copy link
Author

Environment

这个机制不好调整,现在你遇到的问题本质上是使用方式不对

请问我的正确姿势是什么?意思是直接用nacos监听到的配置,而不是直接使用Environment吗?

@XiaZhouxx
Copy link

Environment

这个机制不好调整,现在你遇到的问题本质上是使用方式不对

请问我的正确姿势是什么?意思是直接用nacos监听到的配置,而不是直接使用Environment吗?

我记得文档中刷新配置是基于@RefreshScope实现的, 你可以监听一下这个事件试一下EnvironmentChangeEvent

@shiyiyue1102
Copy link
Contributor

shiyiyue1102 commented Dec 12, 2024

监听

可以使用sca发布的新的nacos注解,https://mp.weixin.qq.com/s/VJrM53Z-gfq94pYVEACdiQ ,看看是不是你需要的功能。

  • @NacosConfig:作用于 SpringBean 的字段,将 Nacos 中指定的配置注入字段;作用于 SpringBean Class,将 Nacos 中指定的配置注入 Bean 的属性中;作用于 FactoryBean 方法,将 Nacos 中指定的配置注入 Bean 的属性中,不依赖 RefreshScope 注解即可生效。

  • @NacosConfigListener:作用于 SpringBean 的方法,在 Nacos 中的配置发生变化时,以方法参数形式接受变更后的最新配置内容,支持以对象类型接收结果。

  • @NacosConfigKeysListener:作用于 SpringBean 的方法,在 Nacos 中的配置的指定属性 key 集合发生变化时,以方法参数 ConfigChangeEvent 接受变更前后的属性值。

@shiyiyue1102
Copy link
Contributor

用法实例:
@NacosConfig(dataId="apaas.application.json", group="apaas")
@bean
ApaasApplicationProperties apaasProperties(){
return new ApaasApplicationProperties();
}

保证在nacos创建的dataId="apaas.application.json", group="apaas" 的配置可以通过json反序列为你的ApaasApplicationProperties对象即可

@shiyiyue1102
Copy link
Contributor

你现在的这个用法用Spring的ConfigurationProperties 注解就行了。。。不需要那些监听回调的逻辑
@ConfigurationProperties(prefix="apaas")
public class ApaasApplicationProperties{
xxx
}

@youngledo
Copy link
Author

你现在的这个用法用Spring的ConfigurationProperties 注解就行了。。。不需要那些监听回调的逻辑 @ConfigurationProperties(prefix="apaas") public class ApaasApplicationProperties{ xxx }

感谢回复。这种确实可以拿到最新的配置,但是其实我想拿到配置改变的事件,以便于通知其他的业务处理。

或许使用EnvironmentChangeEvent是好的方式,但这种方式又拿不到具体的dataId,先这样吧…… 😂

@shiyiyue1102
Copy link
Contributor

  • @NacosConfigListener:作用于 SpringBean 的方法,在 Nacos 中的配置发生变化时,以方法参数形式接受变更后的最新配置内容,支持以对象类型接收结果。

如果你需要接受变更事件,做额外的业务通知,可以使用 新发布的注解
@NacosConfigListener:作用于 SpringBean 的方法,在 Nacos 中的配置发生变化时,以方法参数形式接受变更后的最新配置内容,支持以对象类型接收结果。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/nacos spring cloud alibaba nacos kind/question
Projects
None yet
Development

No branches or pull requests

4 participants