Nacos动态配置

1 篇文章 0 订阅
1 篇文章 0 订阅

Nacos动态配置

一、代码编写

1. yaml配置
nacos:
  config:
    server-addr: ***:8848
    namespace: ****
  accessKey: ****
  secretKey: ****
2. NacosConfig
package com.hho.item.center.config;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Properties;
import java.util.concurrent.Executor;

/**
 * @program: item-center
 * @description:
 * @author: SunYang
 * @create: 2023-10-19
 **/
@Component
@Slf4j
public class NacosConfig {

    private static final String DATA_ID = "***-id";
    private static final String GROUP = "****";
    private static final long DEFAULT_TIMEOUT = 5000;

    @Value("${nacos.config.server-addr}")
    private String nacosServerAddr;
    @Value("${nacos.config.namespace}")
    private String namespace;

    @Value("${nacos.accessKey}")
    private String accessKey;
    @Value("${nacos.secretKey}")
    private String secretKey;

    @PostConstruct
    public void init() {
        try {
            Properties properties = new Properties();
            properties.put(PropertyKeyConst.SERVER_ADDR, nacosServerAddr);
            properties.put(PropertyKeyConst.NAMESPACE, namespace);
            properties.put(PropertyKeyConst.ACCESS_KEY, accessKey);
            properties.put(PropertyKeyConst.SECRET_KEY, secretKey);

            // 创建ConfigService
            ConfigService configService = NacosFactory.createConfigService(properties);
            // 获取配置
            String config = configService.getConfig(DATA_ID, GROUP, DEFAULT_TIMEOUT);
            // 转化成对应的config实体
            NacosJsonConfig nacosJsonConfig = NacosJsonConfig.parse(config);
            // 设置congfig上下文类
            NacosJsonConfigContext.set(nacosJsonConfig);
            log.info("Successfully fetched and set initial configuration from Nacos.");
						
            // 监听更新
            configService.addListener(DATA_ID, GROUP, new Listener() {
                @Override
                public Executor getExecutor() {
                    return null;
                }

                @Override
                public void receiveConfigInfo(String configInfo) {
                    NacosJsonConfig nacosJsonConfig = NacosJsonConfig.parse(configInfo);
                    // 刷新上下文类配置
                    NacosJsonConfigContext.set(nacosJsonConfig);
                    log.info("Received and updated configuration from Nacos.");
                }
            });
        } catch (NacosException e) {
            log.error("Failed to initialize AquamanNoticeConfiguration.", e);
            throw new RuntimeException("INIT_NACOS_ERROR", e);
        }

    }

}

3. config实体
package com.hho.item.center.config;

import com.alibaba.fastjson.JSON;
import lombok.Data;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

/**
 * @program: item-center
 * @description:
 * @author: SunYang
 * @create: 2023-10-19
 **/
@Getter
@Data

public class NacosJsonConfig {
		
    private String itemId;

    public static NacosJsonConfig parse (String config) {
        // 如果config是空,则从配置上下文类中获取,避免因nacos故障导致读取不到配置
        if (StringUtils.isBlank(config)) {
            return NacosJsonConfigContext.get();
        }
        return JSON.parseObject(config, NacosJsonConfig.class);
    }

}
4. NacosJsonConfigContext 上下文类
package com.hho.item.center.config;

/**
 * @program: item-center
 * @description: nacos配置上下文
 * @author: SunYang
 * @create: 2023-10-19
 **/

public class NacosJsonConfigContext {

    // 保证更新对其他线程立即可见
    private static volatile NacosJsonConfig instance = new NacosJsonConfig();

    public static void set(NacosJsonConfig nacosJsonConfig) {
        instance = nacosJsonConfig;
    }

    public static NacosJsonConfig get() {
        return instance;
    }

}

二、代码解析

一、整体解析
  1. NacosConfig.java

    • 这是一个Spring组件,主要用于初始化与Nacos服务器的连接,并从中获取配置信息。

    • 类中定义了一些静态常量如DATA_ID, GROUPDEFAULT_TIMEOUT,它们被用于从Nacos获取配置。

    • 使用@Value注解从Spring环境中注入了Nacos的连接参数。

    • @PostConstruct标记的init()方法将在bean初始化后执行,主要负责以下操作:

      1. 构造连接Nacos所需的属性。
      2. 创建Nacos ConfigService实例。
      3. 使用configService.getConfig()方法获取初始配置。
      4. 将获取的配置解析为NacosJsonConfig对象并设置到NacosJsonConfigContext中。
      5. 向Nacos注册一个监听器,用于监听配置变化。当配置发生变化时,解析新的配置并更新NacosJsonConfigContext
  2. ImQuickJumpTagConfig.java

    • 提供了一个静态的parse方法,将JSON字符串解析为NacosJsonConfig对象。如果提供的字符串为空,它会返回NacosJsonConfigContext中的默认值。
  3. NacosJsonConfigContext.java

    • 这是一个简单的上下文类,用于存储和检索当前的NacosJsonConfig实例。
    • 它包含一个静态的NacosJsonConfig实例,默认为一个新的空实例。
    • 提供了setget方法,分别用于更新和检索NacosJsonConfig实例。

总结:使用Nacos客户端API与Nacos服务器通讯,并在配置发生变化时进行更新。这个配置被保存在一个上下文中,可以在应用的其他部分进行访问和使用。

二、NacosJsonConfigContext 的意义是什么?

NacosJsonConfigContext 类在你的代码中充当了一个中央存储或"上下文"的角色,用于存储当前的 NacosJsonConfigContext 配置实例。该上下文使得其他的代码部分可以轻松访问这个配置,而不必每次都从Nacos或其他来源重新获取。

具体的意义和用途如下:

  1. 集中化的存储:它为 NacosJsonConfigContext 提供了一个集中的存储位置。这意味着,不管配置是从哪里来的(在你的例子中是从Nacos),只要它被解析和设置,其他的代码就可以从这个上下文中获取它。
  2. 简化访问:有了这个上下文,其他的代码部分不需要知道配置的来源或如何解析它。他们只需要调用 NacosJsonConfigContext.get() 就可以获取当前的配置。
  3. 实时更新:如果Nacos中的配置发生了变化,你的代码会自动更新存储在 NacosJsonConfigContext 中的配置实例。这确保了应用程序的其他部分总是能够访问到最新的配置,而不必重新从Nacos获取。
  4. 默认配置:在你的实现中,如果某些原因导致配置不能被解析(例如Nacos返回了空字符串),NacosJsonConfigContext 会返回一个默认的配置实例,从而避免可能的空指针异常或其他错误。
  5. 灵活性:未来,如果你决定更改配置的来源或解析方法,只需要在相应的位置更新 NacosJsonConfigContext,而不必更改所有使用该配置的代码部分。

总之,NacosJsonConfigContext 在你的应用程序中充当了一个中间人的角色,它连接了配置的来源(Nacos)和使用该配置的其他代码部分。这种模式提供了一个集中的存储位置,并简化了配置的访问和更新。

三、涉及的设计模式

代码涉及几个设计模式,具体如下:

  1. 单例模式(Singleton Pattern): 在 ImQuickJumpTagConfigContext 类中,你使用了一个静态的 ImQuickJumpTagConfig 实例来表示全局的单一实例。这是单例模式的一个简化版本,确保了整个应用只有一个 ImQuickJumpTagConfig 实例。虽然你的实现没有使用常见的“双重检查锁定”或“静态内部类”方法来实现线程安全的单例,但其目的与单例模式是一致的。
  2. 观察者模式(Observer Pattern): 你的代码中,通过 Nacos 的 configService.addListener 方法来注册一个监听器,当 Nacos 中的配置发生变化时,这个监听器会被触发,从而实时更新 ImQuickJumpTagConfig 的状态。这就是观察者模式,其中 Nacos 是主题(Subject),而你注册的监听器是观察者(Observer)。
  3. 工厂模式(Factory Pattern): 你使用了 NacosFactory.createConfigService(properties) 来获取 ConfigService 的实例。这里的 NacosFactory 就是一个工厂,它根据给定的属性生成并返回相应的对象。
  4. 上下文模式(Context Pattern): ImQuickJumpTagConfigContext 充当了上下文角色,它封装了特定的状态(ImQuickJumpTagConfig 实例)并为其他对象提供了统一的访问接口。虽然这不是传统的设计模式,但它在软件设计中是一种常见的做法。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值