Nacos配置中心之事件订阅

简介: Nacos配置中心之事件订阅

Nacos配置中心之事件订阅

NacosContextRefresher实现ApplicationListener接口进行事件监听,在上下文准备完毕时候触发这个事件

NacosContextRefresher的onApplicationEvent方法:

@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
   // many Spring context
   if (this.ready.compareAndSet(false, true)) {
      this.registerNacosListenersForApplications();
   }
}

registerNacosListenersForApplications进行Nacos事件监听的注册。

registerNacosListenersForApplications方法:

private void registerNacosListenersForApplications() {
   if (refreshProperties.isEnabled()) {
      for (NacosPropertySource nacosPropertySource : NacosPropertySourceRepository
            .getAll()) {

         if (!nacosPropertySource.isRefreshable()) {
            continue;
         }

         String dataId = nacosPropertySource.getDataId();
         registerNacosListener(nacosPropertySource.getGroup(), dataId);
      }
   }
}

registerNacosListener方法:

private void registerNacosListener(final String group, final String dataId) {

   Listener listener = listenerMap.computeIfAbsent(dataId, i -> new Listener() {
      @Override
      public void receiveConfigInfo(String configInfo) {
         refreshCountIncrement();
         String md5 = "";
         if (!StringUtils.isEmpty(configInfo)) {
            try {
               MessageDigest md = MessageDigest.getInstance("MD5");
               md5 = new BigInteger(1, md.digest(configInfo.getBytes("UTF-8")))
                     .toString(16);
            }
            catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
               log.warn("[Nacos] unable to get md5 for dataId: " + dataId, e);
            }
         }
         refreshHistory.add(dataId, md5);
         applicationContext.publishEvent(
               new RefreshEvent(this, null, "Refresh Nacos config"));
         if (log.isDebugEnabled()) {
            log.debug("Refresh Nacos config group " + group + ",dataId" + dataId);
         }
      }

      @Override
      public Executor getExecutor() {
         return null;
      }
   });

   try {
      configService.addListener(dataId, group, listener);
   }
   catch (NacosException e) {
      e.printStackTrace();
   }
}

registerNacosListener中applicationContext.publishEvent方法发布RefreshEvent事件,事件的监听实现在RefreshEventListener类中

RefreshEventListener类:

/**
 * On application start up, NacosContextRefresher add nacos listeners to all application
 * level dataIds, when there is a change in the data, listeners will refresh
 * configurations.
 *
 * @author juven.xuxb
 * @author pbting
 */
public class NacosContextRefresher
        implements ApplicationListener<ApplicationReadyEvent>, ApplicationContextAware {

    private final static Logger log = LoggerFactory
            .getLogger(NacosContextRefresher.class);

    private static final AtomicLong REFRESH_COUNT = new AtomicLong(0);

    private final NacosRefreshProperties refreshProperties;

    private final NacosRefreshHistory refreshHistory;

    private final ConfigService configService;

    private ApplicationContext applicationContext;

    private AtomicBoolean ready = new AtomicBoolean(false);

    private Map<String, Listener> listenerMap = new ConcurrentHashMap<>(16);

    public NacosContextRefresher(NacosRefreshProperties refreshProperties,
            NacosRefreshHistory refreshHistory, ConfigService configService) {
        this.refreshProperties = refreshProperties;
        this.refreshHistory = refreshHistory;
        this.configService = configService;
    }

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        // many Spring context
        if (this.ready.compareAndSet(false, true)) {
            this.registerNacosListenersForApplications();
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    private void registerNacosListenersForApplications() {
        if (refreshProperties.isEnabled()) {
            for (NacosPropertySource nacosPropertySource : NacosPropertySourceRepository
                    .getAll()) {

                if (!nacosPropertySource.isRefreshable()) {
                    continue;
                }

                String dataId = nacosPropertySource.getDataId();
                registerNacosListener(nacosPropertySource.getGroup(), dataId);
            }
        }
    }

    private void registerNacosListener(final String group, final String dataId) {

        Listener listener = listenerMap.computeIfAbsent(dataId, i -> new Listener() {
            @Override
            public void receiveConfigInfo(String configInfo) {
                refreshCountIncrement();
                String md5 = "";
                if (!StringUtils.isEmpty(configInfo)) {
                    try {
                        MessageDigest md = MessageDigest.getInstance("MD5");
                        md5 = new BigInteger(1, md.digest(configInfo.getBytes("UTF-8")))
                                .toString(16);
                    }
                    catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
                        log.warn("[Nacos] unable to get md5 for dataId: " + dataId, e);
                    }
                }
                refreshHistory.add(dataId, md5);
                applicationContext.publishEvent(
                        new RefreshEvent(this, null, "Refresh Nacos config"));
                if (log.isDebugEnabled()) {
                    log.debug("Refresh Nacos config group " + group + ",dataId" + dataId);
                }
            }

            @Override
            public Executor getExecutor() {
                return null;
            }
        });

        try {
            configService.addListener(dataId, group, listener);
        }
        catch (NacosException e) {
            e.printStackTrace();
        }
    }

    public static long getRefreshCount() {
        return REFRESH_COUNT.get();
    }

    public static void refreshCountIncrement() {
        REFRESH_COUNT.incrementAndGet();
    }
}

handler方法中调用refresh.refresh()方法完成配置的更新和应用。

相关文章
|
3月前
|
Java Nacos 数据库
使用 nacos 搭建注册中心及配置中心
使用 nacos 搭建注册中心及配置中心
82 5
|
3月前
|
NoSQL Java Nacos
SpringCloud集成Seata并使用Nacos做注册中心与配置中心
SpringCloud集成Seata并使用Nacos做注册中心与配置中心
83 3
|
27天前
|
负载均衡 Java Nacos
SpringCloud基础2——Nacos配置、Feign、Gateway
nacos配置管理、Feign远程调用、Gateway服务网关
SpringCloud基础2——Nacos配置、Feign、Gateway
|
2月前
|
安全 Nacos 数据安全/隐私保护
升级指南:从Nacos 1.3.0 到 2.3.0,并兼容 Seata 的鉴权配置
本文详细介绍了如何在微服务环境下从 Nacos 1.3.0 升级到 2.3.0,并确保 Seata 各版本的兼容性。作者小米分享了升级过程中的关键步骤,包括备份配置、更新鉴权信息及验证测试等,并解答了常见问题。通过这些步骤,可以帮助读者顺利完成升级并提高系统的安全性与一致性。
88 8
升级指南:从Nacos 1.3.0 到 2.3.0,并兼容 Seata 的鉴权配置
|
2月前
|
运维 Java Nacos
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心
|
2月前
|
应用服务中间件 Nacos 数据库
Nacos 1.2.1 集群搭建(三) Nginx 配置 集群
Nacos 1.2.1 集群搭建(三) Nginx 配置 集群
53 1
|
2月前
|
SQL 关系型数据库 MySQL
Nacos 1.2.1 集群搭建(二)MySQL、cluster 配置
Nacos 1.2.1 集群搭建(二)MySQL、cluster 配置
53 1
|
2月前
|
缓存 Cloud Native Java
【紧急救援】Nacos配置上线后失效?手把手教你如何轻松搞定命名空间修改难题!
【8月更文挑战第15天】Nacos是关键的云原生服务管理平台,用于动态服务发现与配置管理。但在使用其管理微服务配置时,可能会遇到命名空间内的配置更新后不生效的问题。本文探讨此问题并提供解决方案。首先需确认Nacos服务器运行正常及客户端正确连接。接着检查客户端缓存配置,可通过禁用缓存或缩短缓存间隔来即时更新配置。例如,在Spring Cloud Alibaba Nacos配置中心中启用自动刷新功能,并设置每5秒拉取新配置。同时,对于新增配置项,需重启客户端应用。还需检查Nacos服务器日志排除异常,并考虑升级Nacos版本解决兼容性问题。通过这些步骤,通常可有效解决配置不生效的难题。
77 0
|
2月前
|
安全 Nacos 数据库
【技术安全大揭秘】Nacos暴露公网后被非法访问?!6大安全加固秘籍,手把手教你如何保护数据库免遭恶意篡改,打造坚不可摧的微服务注册与配置中心!从限制公网访问到启用访问控制,全方位解析如何构建安全防护体系,让您从此告别数据安全风险!
【8月更文挑战第15天】Nacos是一款广受好评的微服务注册与配置中心,但其公网暴露可能引发数据库被非法访问甚至篡改的安全隐患。本文剖析此问题并提供解决方案,包括限制公网访问、启用HTTPS、加强数据库安全、配置访问控制及监控等,帮助开发者确保服务安全稳定运行。
131 0
|
2月前
|
安全 Nacos 数据安全/隐私保护
【技术干货】破解Nacos安全隐患:连接用户名与密码明文传输!掌握HTTPS、JWT与OAuth2.0加密秘籍,打造坚不可摧的微服务注册与配置中心!从原理到实践,全方位解析如何构建安全防护体系,让您从此告别数据泄露风险!
【8月更文挑战第15天】Nacos是一款广受好评的微服务注册与配置中心,但其连接用户名和密码的明文传输成为安全隐患。本文探讨加密策略提升安全性。首先介绍明文传输风险,随后对比三种加密方案:HTTPS简化数据保护;JWT令牌减少凭证传输,适配分布式环境;OAuth2.0增强安全,支持多授权模式。每种方案各有千秋,开发者需根据具体需求选择最佳实践,确保服务安全稳定运行。
123 0

热门文章

最新文章