Nacos Config配置监听比Spring的Environment要快,导致获取的配置还是旧的。
Closed this issue · 10 comments
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秒),则能正常拿到最新的配置,睡眠代码如下:
Expected behavior
在监听到nacos配置有变化时,通过Spring的Environment能拿到最新的配置。
从机制上,nacos的配置是最终一致性,nacos多个监听器之间并没有依赖关系,nacos保证的是通过监听器receiveConfigInfo接收到的是最新的配置,但不保证其他的监听器(更新Spring Enviroment)已经接受到了最新的结果
这个机制是否有可能做些调整,毕竟nacos的配置最终还是要刷新到Spring Environment中?
Environment
这个机制不好调整,现在你遇到的问题本质上是使用方式不对
Environment
这个机制不好调整,现在你遇到的问题本质上是使用方式不对
请问我的正确姿势是什么?意思是直接用nacos监听到的配置,而不是直接使用Environment吗?
Environment
这个机制不好调整,现在你遇到的问题本质上是使用方式不对
请问我的正确姿势是什么?意思是直接用nacos监听到的配置,而不是直接使用Environment吗?
我记得文档中刷新配置是基于@RefreshScope
实现的, 你可以监听一下这个事件试一下EnvironmentChangeEvent
监听
可以使用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 接受变更前后的属性值。
用法实例:
@NacosConfig(dataId="apaas.application.json", group="apaas")
@bean
ApaasApplicationProperties apaasProperties(){
return new ApaasApplicationProperties();
}
保证在nacos创建的dataId="apaas.application.json", group="apaas" 的配置可以通过json反序列为你的ApaasApplicationProperties对象即可
你现在的这个用法用Spring的ConfigurationProperties 注解就行了。。。不需要那些监听回调的逻辑
@ConfigurationProperties(prefix="apaas")
public class ApaasApplicationProperties{
xxx
}
你现在的这个用法用Spring的ConfigurationProperties 注解就行了。。。不需要那些监听回调的逻辑 @ConfigurationProperties(prefix="apaas") public class ApaasApplicationProperties{ xxx }
感谢回复。这种确实可以拿到最新的配置,但是其实我想拿到配置改变的事件,以便于通知其他的业务处理。
或许使用EnvironmentChangeEvent
是好的方式,但这种方式又拿不到具体的dataId,先这样吧…… 😂
- @NacosConfigListener:作用于 SpringBean 的方法,在 Nacos 中的配置发生变化时,以方法参数形式接受变更后的最新配置内容,支持以对象类型接收结果。
如果你需要接受变更事件,做额外的业务通知,可以使用 新发布的注解
@NacosConfigListener:作用于 SpringBean 的方法,在 Nacos 中的配置发生变化时,以方法参数形式接受变更后的最新配置内容,支持以对象类型接收结果。