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

在配置中心删除某项配置之后无法将这项配置更新为空值 #12690

Closed
spice-wolf opened this issue Sep 25, 2024 · 17 comments
Closed
Labels
area/Spring Cloud Related to Spring Cloud kind/question Category issues related to questions or problems

Comments

@spice-wolf
Copy link

Describe the bug
例如,在配置中心上有一项配置:

test-config: 测试配置1

如果把这项配置完全删除掉,程序中读取到的testConfig值还是测试配置1,但是期望的testConfig值应该是null

从程序的日志中可以看到nacos-client拿到了变动后的配置,并且准确地报告了是test-config这个配置项有变更。我大概了解配置动态刷新的原理:拿到变更后的配置,将其中的配置项与程序当前的配置项相比较,如果不相等则刷新对应的配置项的值。是否是因为变更后的配置中test-config这个配置项被删除掉了,导致无法和程序的值进行比较,所以没有更新程序中的值呢?

我觉得删除配置项这个动作,在大部分情况下是期望将这个配置项更新为null或者使用默认值(如果有默认值的话),所以我觉得当前的处理不太符合使用者的直觉,很大可能会造成隐患。

我在这个仓库的issues中找到了一个类似的问题:#11170 ,但它目前是closed状态。我现在还无法确定这是nacos的问题,还是spring cloud的问题(因为我当前使用的依赖是spring-cloud-starter-alibaba-nacos-config),所以我提了这个issue来寻找一下答案以及后续的处理。期待回复~

Expected behavior
删除掉配置中心上的配置项之后,程序中的对应配置项应该刷新为null或者默认值,或者其他更好的处理

Actually behavior
实际上,目前删除掉配置中心上的配置项之后,程序中的对应配置项没有任何变化,还保留着最后一次生效的值

How to Reproduce
使用spring-cloud-starter-alibaba-nacos-config:2023.0.1.0按照上述描述去操作即可复现

Desktop (please complete the following information):

  • OS: [不重要]
  • Version [nacos-client 2.3.2]
  • Module [不重要]
  • SDK [[spring-cloud-alibaba-nacos](spring-cloud-starter-alibaba-nacos-config 2023.0.1.0)]

Additional context
nothing

@XiaZhouxx
Copy link
Contributor

我测试是生效了的, 你配置类有使用@RefreshScope注解吗?

@spice-wolf
Copy link
Author

我测试是生效了的, 你配置类有使用@RefreshScope注解吗?

好吧,是我不严谨了。我测试了在配置类上使用以及不使用@RefreshScope注解这两种情况:

  1. 在配置类上使用@RefreshScope注解时:修改配置中心上的配置项,正常动态刷新为修改后的值;将配置中心上的配置项删除,也正常动态刷新为null。这是符合期望的行为
  2. 在配置类上不使用@RefreshScope注解时:修改配置中心上的配置项,正常动态刷新为修改后的值;将配置中心上的配置项删除,没有正常动态刷新为null,而是继续保持了最后一次生效的值。这是不符合期望的行为

根据测试结果来看,似乎并不是nacos的问题🤐?

@XiaZhouxx
Copy link
Contributor

我测试是生效了的, 你配置类有使用@RefreshScope注解吗?

好吧,是我不严谨了。我测试了在配置类上使用以及不使用@RefreshScope注解这两种情况:

  1. 在配置类上使用@RefreshScope注解时:修改配置中心上的配置项,正常动态刷新为修改后的值;将配置中心上的配置项删除,也正常动态刷新为null。这是符合期望的行为
  2. 在配置类上不使用@RefreshScope注解时:修改配置中心上的配置项,正常动态刷新为修改后的值;将配置中心上的配置项删除,没有正常动态刷新为null,而是继续保持了最后一次生效的值。这是不符合期望的行为

根据测试结果来看,似乎并不是nacos的问题🤐?

那就奇怪了 使用spring-cloud-starter-alibaba-nacos-config按道理没加@RefreshScope是动态刷新不了的

@spice-wolf
Copy link
Author

spice-wolf commented Sep 26, 2024

我测试是生效了的, 你配置类有使用@RefreshScope注解吗?

好吧,是我不严谨了。我测试了在配置类上使用以及不使用@RefreshScope注解这两种情况:

  1. 在配置类上使用@RefreshScope注解时:修改配置中心上的配置项,正常动态刷新为修改后的值;将配置中心上的配置项删除,也正常动态刷新为null。这是符合期望的行为
  2. 在配置类上不使用@RefreshScope注解时:修改配置中心上的配置项,正常动态刷新为修改后的值;将配置中心上的配置项删除,没有正常动态刷新为null,而是继续保持了最后一次生效的值。这是不符合期望的行为

根据测试结果来看,似乎并不是nacos的问题🤐?

那就奇怪了 使用spring-cloud-starter-alibaba-nacos-config按道理没加@RefreshScope是动态刷新不了的

spring-cloud-starter-alibaba-nacos-config做了增强呀,如果你在配置类上加了@ConfigurationProperties注解(一般来说,配置类都会加上这个注解),但是没加@RefreshScope也是可以正常动态刷新的。只是在删除配置时没法正常刷新成null值,这一点我感觉很奇怪。如果加上@RefreshScope注解时支持这样的操作,那么没加@RefreshScope注解时是不是也应该支持这样的操作才对?这样逻辑才是统一的

@misakacoder
Copy link
Contributor

我测试是生效了的, 你配置类有使用@RefreshScope注解吗?

好吧,是我不严谨了。我测试了在配置类上使用以及不使用@RefreshScope注解这两种情况:

  1. 在配置类上使用@RefreshScope注解时:修改配置中心上的配置项,正常动态刷新为修改后的值;将配置中心上的配置项删除,也正常动态刷新为null。这是符合期望的行为
  2. 在配置类上不使用@RefreshScope注解时:修改配置中心上的配置项,正常动态刷新为修改后的值;将配置中心上的配置项删除,没有正常动态刷新为null,而是继续保持了最后一次生效的值。这是不符合期望的行为

根据测试结果来看,似乎并不是nacos的问题🤐?

那就奇怪了 使用spring-cloud-starter-alibaba-nacos-config按道理没加@RefreshScope是动态刷新不了的

使用spring-cloud-starter-alibaba-nacos-config但是没加@RefreshScope是可以正常动态刷新的,只是在删除配置时没法正常刷新成null值,这一点我也感觉很奇怪。如果加上@RefreshScope注解时支持这样的操作,那么没加@RefreshScope注解时是不是也应该支持这样的操作才对?这样逻辑才是统一的

不加@RefreshScope刷新不了哦,我这边刚好有个demo测试了一下,nacos是2.4.2,spring-cloud-starter-alibaba-nacos-config是2023.0.1.2

@XiaZhouxx
Copy link
Contributor

我测试是生效了的, 你配置类有使用@RefreshScope注解吗?

好吧,是我不严谨了。我测试了在配置类上使用以及不使用@RefreshScope注解这两种情况:

  1. 在配置类上使用@RefreshScope注解时:修改配置中心上的配置项,正常动态刷新为修改后的值;将配置中心上的配置项删除,也正常动态刷新为null。这是符合期望的行为
  2. 在配置类上不使用@RefreshScope注解时:修改配置中心上的配置项,正常动态刷新为修改后的值;将配置中心上的配置项删除,没有正常动态刷新为null,而是继续保持了最后一次生效的值。这是不符合期望的行为

根据测试结果来看,似乎并不是nacos的问题🤐?

那就奇怪了 使用spring-cloud-starter-alibaba-nacos-config按道理没加@RefreshScope是动态刷新不了的

使用spring-cloud-starter-alibaba-nacos-config但是没加@RefreshScope是可以正常动态刷新的,只是在删除配置时没法正常刷新成null值,这一点我也感觉很奇怪。如果加上@RefreshScope注解时支持这样的操作,那么没加@RefreshScope注解时是不是也应该支持这样的操作才对?这样逻辑才是统一的

但是实际上的实现逻辑也是需要加上注解才能动态刷新, 官方文档也提到了我本地测试也是这样, 我奇怪的是居然没加可以实现动态刷新.

@spice-wolf
Copy link
Author

不加@RefreshScope刷新不了哦,我这边刚好有个demo测试了一下,nacos是2.4.2,spring-cloud-starter-alibaba-nacos-config是2023.0.1.2

spring-cloud-starter-alibaba-nacos-config做了增强呀,如果你在配置类上加了@ConfigurationProperties注解也是支持动态刷新的

@spice-wolf
Copy link
Author

但是实际上的实现逻辑也是需要加上注解才能动态刷新, 官方文档也提到了我本地测试也是这样, 我奇怪的是居然没加可以实现动态刷新.

spring-cloud-starter-alibaba-nacos-config做了增强呀,如果你在配置类上加了@ConfigurationProperties注解也是支持动态刷新的

@spice-wolf
Copy link
Author

我们先对齐一下我们的问题复现demo吧😂
下面是我用来复现问题的demo:

  1. 配置类TestConfig
@Data
@Configuration
@ConfigurationProperties(prefix = "test")
public class TestConfig {

    private String config;
}
  1. 一个打印配置的程序:
@Component
@RequiredArgsConstructor
public class TestConfigPrinter implements CommandLineRunner {

    private final TestConfig testConfig;

    @Override
    public void run(String... args) throws Exception {
        new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                System.out.println("测试配置:" + testConfig.getConfig());
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
    }
}

可以依次:test.config配置项的值改成配置1、将test.config配置项的值改成配置2、将test.config配置项删除掉 来观察控制台输出从而复现问题

@XiaZhouxx
Copy link
Contributor

我们先对齐一下我们的问题复现demo吧😂 下面是我用来复现问题的demo:

  1. 配置类TestConfig
@Data
@Configuration
@ConfigurationProperties(prefix = "test")
public class TestConfig {

    private String config;
}
  1. 一个打印配置的程序:
@Component
@RequiredArgsConstructor
public class TestConfigPrinter implements CommandLineRunner {

    private final TestConfig testConfig;

    @Override
    public void run(String... args) throws Exception {
        new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                System.out.println("测试配置:" + testConfig.getConfig());
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
    }
}

可以依次:test.config配置项的值改成配置1、将test.config配置项的值改成配置2、将test.config配置项删除掉 来观察控制台输出从而复现问题

是的 我看了一下确实, 我测试用的@Value

@XiaZhouxx
Copy link
Contributor

看了一下大概逻辑是spring-cloud提供的ConfigurationPropertiesRebinder 我大概看了一下逻辑应该就是从项目配置中找到对应的配置绑定set值进去, 如果没有找到对应配置就不设置值,此时就保留了上一次的值

@XiaZhouxx
Copy link
Contributor

@RefreshScope标识的类如果刷新会重新创建一个配置bean, 没有找到配置的情况就是默认配置值/空值

@spice-wolf
Copy link
Author

是的👍所以这个问题该不该修复呢?我感觉还是把值设置为null会合理一些,和@RefreshScope的逻辑保持一致

@XiaZhouxx
Copy link
Contributor

是的👍所以这个问题该不该修复呢?我感觉还是把值设置为null会合理一些,和@RefreshScope的逻辑保持一致

这个不是问题吧, 首先这两个注解是spring-cloud提供的实现,看可以去spring-cloud-alibaba社区提个issue, 然后这里官方文档也明确说明使用@RefreshScope来实现配置动态更新
https://nacos.io/docs/latest/ecology/use-nacos-with-spring-cloud/#%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86

@spice-wolf
Copy link
Author

是的👍所以这个问题该不该修复呢?我感觉还是把值设置为null会合理一些,和@RefreshScope的逻辑保持一致

这个不是问题吧, 首先这两个注解是spring-cloud提供的实现,看可以去spring-cloud-alibaba社区提个issue, 然后这里官方文档也明确说明使用@RefreshScope来实现配置动态更新 https://nacos.io/docs/latest/ecology/use-nacos-with-spring-cloud/#%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86

我会觉得这是个问题,要么不加@RefreshScope注解时就不要支持动态刷新,要么就和加上@RefreshScope注解时的动态刷新逻辑保持一致。但确实,这不是Nacos的问题。我会去spring-cloud-alibaba社区看看,如果还没有人提问过这个问题,我会提个issue
感谢你的解答😀

@XiaZhouxx
Copy link
Contributor

是的👍所以这个问题该不该修复呢?我感觉还是把值设置为null会合理一些,和@RefreshScope的逻辑保持一致

这个不是问题吧, 首先这两个注解是spring-cloud提供的实现,看可以去spring-cloud-alibaba社区提个issue, 然后这里官方文档也明确说明使用@RefreshScope来实现配置动态更新 https://nacos.io/docs/latest/ecology/use-nacos-with-spring-cloud/#%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86

我会觉得这是个问题,要么不加@RefreshScope注解时就不要支持动态刷新,要么就和加上@RefreshScope注解时的动态刷新逻辑保持一致。但确实,这不是Nacos的问题。我会去spring-cloud-alibaba社区看看,如果还没有人提问过这个问题,我会提个issue 感谢你的解答😀

看了一下应该是spring-cloud社区在考虑增强 spring-cloud/spring-cloud-commons#1372

@spice-wolf
Copy link
Author

是的👍所以这个问题该不该修复呢?我感觉还是把值设置为null会合理一些,和@RefreshScope的逻辑保持一致

这个不是问题吧, 首先这两个注解是spring-cloud提供的实现,看可以去spring-cloud-alibaba社区提个issue, 然后这里官方文档也明确说明使用@RefreshScope来实现配置动态更新 https://nacos.io/docs/latest/ecology/use-nacos-with-spring-cloud/#%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86

我会觉得这是个问题,要么不加@RefreshScope注解时就不要支持动态刷新,要么就和加上@RefreshScope注解时的动态刷新逻辑保持一致。但确实,这不是Nacos的问题。我会去spring-cloud-alibaba社区看看,如果还没有人提问过这个问题,我会提个issue 感谢你的解答😀

看了一下应该是spring-cloud社区在考虑增强 spring-cloud/spring-cloud-commons#1372

好的,非常感谢👍

@KomachiSion KomachiSion closed this as not planned Won't fix, can't repro, duplicate, stale Sep 27, 2024
@KomachiSion KomachiSion added kind/question Category issues related to questions or problems area/Spring Cloud Related to Spring Cloud labels Sep 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/Spring Cloud Related to Spring Cloud kind/question Category issues related to questions or problems
Projects
None yet
Development

No branches or pull requests

4 participants