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天前
|
负载均衡 应用服务中间件 Nacos
Nacos配置中心
Nacos配置中心
19 1
Nacos配置中心
|
3天前
|
网络安全 Nacos 开发者
Nacos作为流行的微服务注册与配置中心,“节点提示暂时不可用”是常见的问题之一
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,“节点提示暂时不可用”是常见的问题之一。本文将探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务的正常运行。通过检查服务实例状态、网络连接、Nacos配置、调整健康检查策略等步骤,可以有效解决这一问题。
12 4
|
3天前
|
Java 网络安全 Nacos
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,实际使用中常遇到“客户端不发送心跳检测”的问题。本文深入探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务正常运行。通过检查客户端配置、网络连接、日志、版本兼容性、心跳策略、注册状态、重启应用和环境变量等步骤,系统地排查和解决这一问题。
12 3
|
3天前
|
安全 Nacos 数据库
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改。本文详细探讨了这一问题的原因及解决方案,包括限制公网访问、使用HTTPS、强化数据库安全、启用访问控制、监控和审计等步骤,帮助开发者确保服务的安全运行。
12 3
|
11天前
|
SQL 关系型数据库 数据库连接
"Nacos 2.1.0版本数据库配置写入难题破解攻略:一步步教你排查连接、权限和配置问题,重启服务轻松解决!"
【10月更文挑战第23天】在使用Nacos 2.1.0版本时,可能会遇到无法将配置信息写入数据库的问题。本文将引导你逐步解决这一问题,包括检查数据库连接、用户权限、Nacos配置文件,并提供示例代码和详细步骤。通过这些方法,你可以有效解决配置写入失败的问题。
35 0
|
2月前
|
负载均衡 Java Nacos
SpringCloud基础2——Nacos配置、Feign、Gateway
nacos配置管理、Feign远程调用、Gateway服务网关
SpringCloud基础2——Nacos配置、Feign、Gateway
|
3月前
|
安全 Nacos 数据安全/隐私保护
升级指南:从Nacos 1.3.0 到 2.3.0,并兼容 Seata 的鉴权配置
本文详细介绍了如何在微服务环境下从 Nacos 1.3.0 升级到 2.3.0,并确保 Seata 各版本的兼容性。作者小米分享了升级过程中的关键步骤,包括备份配置、更新鉴权信息及验证测试等,并解答了常见问题。通过这些步骤,可以帮助读者顺利完成升级并提高系统的安全性与一致性。
115 8
升级指南:从Nacos 1.3.0 到 2.3.0,并兼容 Seata 的鉴权配置
|
3月前
|
运维 Java Nacos
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心
|
3月前
|
缓存 Cloud Native Java
【紧急救援】Nacos配置上线后失效?手把手教你如何轻松搞定命名空间修改难题!
【8月更文挑战第15天】Nacos是关键的云原生服务管理平台,用于动态服务发现与配置管理。但在使用其管理微服务配置时,可能会遇到命名空间内的配置更新后不生效的问题。本文探讨此问题并提供解决方案。首先需确认Nacos服务器运行正常及客户端正确连接。接着检查客户端缓存配置,可通过禁用缓存或缩短缓存间隔来即时更新配置。例如,在Spring Cloud Alibaba Nacos配置中心中启用自动刷新功能,并设置每5秒拉取新配置。同时,对于新增配置项,需重启客户端应用。还需检查Nacos服务器日志排除异常,并考虑升级Nacos版本解决兼容性问题。通过这些步骤,通常可有效解决配置不生效的难题。
172 0
|
3月前
|
安全 Nacos 数据库
【技术安全大揭秘】Nacos暴露公网后被非法访问?!6大安全加固秘籍,手把手教你如何保护数据库免遭恶意篡改,打造坚不可摧的微服务注册与配置中心!从限制公网访问到启用访问控制,全方位解析如何构建安全防护体系,让您从此告别数据安全风险!
【8月更文挑战第15天】Nacos是一款广受好评的微服务注册与配置中心,但其公网暴露可能引发数据库被非法访问甚至篡改的安全隐患。本文剖析此问题并提供解决方案,包括限制公网访问、启用HTTPS、加强数据库安全、配置访问控制及监控等,帮助开发者确保服务安全稳定运行。
318 0