转载自 https://blog.csdn.net/WANTAWAY314/article/details/118489812

1,现象

https://[github](https://so.csdn.net/so/search?q=github&spm=1001.2101.3001.7020).com/alibaba/nacos/issues/3803
正常情况下,更新nacos上的kv配置,客户端可以感知到,并且可以“实时”获取到最新的nacos配置。但是如果删除nacos的kv配置,客户端却依旧读取到的是旧的配置;


2,解释

删除 nacos 上的配置后,客户端其实读取到的是客户端内存中的配置,nacos 将删除的 kv 变更没有同步到到客户端。所以感官上看到客户端依旧读的是 “老的配置”;


3,解决

实现 ApplicationListener 类,当有任何 RefreshEvent 变更的时候,将自己本地配置置空。具体代码如下:

  1. import static java.util.Collections.emptyMap;
  2. import javax.annotation.Resource;
  3. import org.springframework.cloud.endpoint.event.RefreshEvent;
  4. import org.springframework.context.ApplicationListener;
  5. import org.springframework.core.Ordered;
  6. import org.springframework.stereotype.Component;
  7. /**
  8. * @author water
  9. * @desc 修复nacos的bug(删除nacos配置,但是SpringCloud还是能读到)
  10. * https://github.com/alibaba/nacos/issues/3803)
  11. */
  12. @Component
  13. public class CleanupRamConfig implements ApplicationListener<RefreshEvent>, Ordered {
  14. @Resource
  15. private MerchantKey merchantKey;
  16. @Override
  17. public void onApplicationEvent(RefreshEvent event) {
  18. merchantKey.setKeyAndSecrets(emptyMap());
  19. }
  20. @Override
  21. public int getOrder() {
  22. return Ordered.HIGHEST_PRECEDENCE;
  23. }
  24. }
  1. import lombok.Data;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import org.springframework.stereotype.Component;
  4. import java.util.Map;
  5. /**
  6. * @author water
  7. * @desc 存储商户鉴权信息
  8. */
  9. @Data
  10. @Component
  11. @ConfigurationProperties(prefix = "merchant")
  12. public class MerchantKey {
  13. private Map<String, String> keyAndSecrets;
  14. }

nacos 中的配置

  1. merchant:
  2. keyAndSecrets:
  3. appKey1: appValue1
  4. appKey2: appValue2
  5. appKey3: appValue3

4, 思考

nacos 这样做真的是 bug 吗? 假如将 nacos 的一个 kv 删除,客户端也清空一个 kv,达到极限,nacos 上的所有 kv 都删除,客户端的所有 kv 也删除。两种情况,1,正常情况下删除 nacos 的所有 kv,那边客户端的所有 kv 清空,这算正常。2,异常情况下,如果 nacos 挂了,客户端检查拿不到远程配置,也清空所有本地 kv,这样是不是有问题;

5,建议

nacos 可以增加一个配置:CleanupRam 默认设置为 false(如果远程 nacos 的 kv 删除,不清理本地内存),如果用户修改为 true(远程 nacos 的 kv 删除,清理本地 kv)