首页 > 编程语言 >2.nacos-client源码及查看

2.nacos-client源码及查看

时间:2023-06-25 11:33:23浏览次数:43  
标签:dataId group String nacos client content 源码 NacosException throws

nacos-client.2.2.1-RC. SDK查看源码

官网JAVA SDK 链接

  • 主要内容
    <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>${version}</version> </dependency>
    问题:1.获取配置api 是获取快照还是远程配置中心?
    2.快照文件默认存储在哪?然后配置?

配置管理

  • 获取配置
    描述
    用于服务启动的时候从 Nacos 获取配置。
    public String getConfig(String dataId, String group, long timeoutMs) throws NacosException

  • 监听配置
    描述
    如果希望 Nacos 推送配置变更,可以使用 Nacos 动态监听配置接口来实现。
    public void addListener(String dataId, String group, Listener listener)

  • 删除监听
    描述
    取消监听配置,取消监听后配置不会再推送。
    public void removeListener(String dataId, String group, Listener listener)

  • 发布配置
    描述
    用于通过程序自动发布 Nacos 配置,以便通过自动化手段降低运维成本。

    注意:创建和修改配置时使用的同一个发布接口,当配置不存在时会创建配置,当配置已存在时会更新配置。

    点击查看代码
      public boolean publishConfig(String dataId, String group, String content) throws NacosException;
      @Since 1.4.1
      public boolean publishConfig(String dataId, String group, String content, String type) throws NacosException;
    
    
  • 删除配置
    描述
    用于通过程序自动删除 Nacos 配置,以便通过自动化手段降低运维成本。

    注意: 当配置已存在时会删除该配置,当配置不存在时会直接返回成功消息。
    public boolean removeConfig(String dataId, String group) throws NacosException

服务发现SDK

  • 注册实例
    描述注册一个实例到服务。
    void registerInstance(String serviceName, String ip, int port) throws NacosException;
    void registerInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;
    void registerInstance(String serviceName, Instance instance) throws NacosException;

  • 注销实例
    描述
    删除服务下的一个实例。
    void deregisterInstance(String serviceName, String ip, int port) throws NacosException;
    void deregisterInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;

  • 获取全部实例
    描述
    获取服务下的所有实例。
    List<Instance> getAllInstances(String serviceName) throws NacosException;
    List<Instance> getAllInstances(String serviceName, List<String> clusters) throws NacosException;

  • 监听服务
    描述
    监听服务下的实例列表变化。
    void subscribe(String serviceName, EventListener listener) throws NacosException;
    void subscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException;


源码实现

配置中心

下载源码包,在api包下config文件下,粗略浏览一下我们发现了 com.alibaba.nacos.api.config.ConfigService 接口:

点击查看代码
public interface ConfigService {
    
    /**
     * Get config.
     *
     * @param dataId    dataId
     * @param group     group
     * @param timeoutMs read timeout
     * @return config value
     * @throws NacosException NacosException
     */
    String getConfig(String dataId, String group, long timeoutMs) throws NacosException;
    
    /**
     * Get config and register Listener.
     *
     * <p>If you want to pull it yourself when the program starts to get the configuration for the first time, and the
     * registered Listener is used for future configuration updates, you can keep the original code unchanged, just add
     * the system parameter: enableRemoteSyncConfig = "true" ( But there is network overhead); therefore we recommend
     * that you use this interface directly
     *
     * @param dataId    dataId
     * @param group     group
     * @param timeoutMs read timeout
     * @param listener  {@link Listener}
     * @return config value
     * @throws NacosException NacosException
     */
    String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener)
            throws NacosException;
    
    /**
     * Add a listener to the configuration, after the server modified the configuration, the client will use the
     * incoming listener callback. Recommended asynchronous processing, the application can implement the getExecutor
     * method in the ManagerListener, provide a thread pool of execution. If not provided, use the main thread callback, May
     * block other configurations or be blocked by other configurations.
     *
     * @param dataId   dataId
     * @param group    group
     * @param listener listener
     * @throws NacosException NacosException
     */
    void addListener(String dataId, String group, Listener listener) throws NacosException;
    
    /**
     * Publish config.
     *
     * @param dataId  dataId
     * @param group   group
     * @param content content
     * @return Whether publish
     * @throws NacosException NacosException
     */
    boolean publishConfig(String dataId, String group, String content) throws NacosException;
    
    
    /**
     * Publish config.
     *
     * @param dataId  dataId
     * @param group   group
     * @param content content
     * @param type    config type {@link ConfigType}
     * @return Whether publish
     * @throws NacosException NacosException
     */
    boolean publishConfig(String dataId, String group, String content, String type) throws NacosException;
    
    /**
     * Cas Publish config.
     *
     * @param dataId  dataId
     * @param group   group
     * @param content content
     * @param casMd5  casMd5 prev content's md5 to cas.
     * @return Whether publish
     * @throws NacosException NacosException
     */
    boolean publishConfigCas(String dataId, String group, String content, String casMd5) throws NacosException;
    
    /**
     * Cas Publish config.
     *
     * @param dataId  dataId
     * @param group   group
     * @param content content
     * @param casMd5  casMd5 prev content's md5 to cas.
     * @param type    config type {@link ConfigType}
     * @return Whether publish
     * @throws NacosException NacosException
     */
    boolean publishConfigCas(String dataId, String group, String content, String casMd5, String type)
            throws NacosException;
    
    /**
     * Remove config.
     *
     * @param dataId dataId
     * @param group  group
     * @return whether remove
     * @throws NacosException NacosException
     */
    boolean removeConfig(String dataId, String group) throws NacosException;
    
    /**
     * Remove listener.
     *
     * @param dataId   dataId
     * @param group    group
     * @param listener listener
     */
    void removeListener(String dataId, String group, Listener listener);
    
    /**
     * Get server status.
     *
     * @return whether health
     */
    String getServerStatus();

    /**
     * add config filter.
     * It is recommended to use {@link com.alibaba.nacos.api.config.filter.AbstractConfigFilter} to expand the filter.
     *
     * @param configFilter filter
     * @since 2.3.0
     */
    void addConfigFilter(IConfigFilter configFilter);
    
    /**
     * Shutdown the resource service.
     *
     * @throws NacosException exception.
     */
    void shutDown() throws NacosException;
}

获取配置信息getConfig

查看getConfig(String dataId, String group, long timeoutMs) 的实现:调用了

getConfigInner(namespace, dataId, group, timeoutMs);

在参数处理中:
grop处理, 未设置返回默认分组DEFAULT_GROUP:

return (StringUtils.isBlank(group)) ? Constants.DEFAULT_GROUP : group.trim();

接下来我看到先去nacos服务器故障本地缓存取:

点击查看代码
        // We first try to use local failover content if exists.
        // A config content for failover is not created by client program automatically,
        // but is maintained by user.
        // This is designed for certain scenario like client emergency reboot,
        // changing config needed in the same time, while nacos server is down.
        String content = LocalConfigInfoProcessor.getFailover(worker.getAgentName(), dataId, group, tenant);
        if (content != null) {
            LOGGER.warn("[{}] [get-config] get failover ok, dataId={}, group={}, tenant={}, config={}",
                    worker.getAgentName(), dataId, group, tenant, ContentUtils.truncateContent(content));
            cr.setContent(content);
            String encryptedDataKey = LocalEncryptedDataKeyProcessor
                    .getEncryptDataKeyFailover(agent.getName(), dataId, group, tenant);
            cr.setEncryptedDataKey(encryptedDataKey);
            configFilterChainManager.doFilter(null, cr);
            content = cr.getContent();
            return content;
        }
查看getFailover,他就是读取本地文件,我们也发现了目录的默认读取地址是 user\home\nacos\config (若想修改配置变量:JM.SNAPSHOT.PATH即可替换); 在该目录下读取{serverName}_nacos\data目录, 没有设置元空间,及config-data-tenant\{group}\{dataId},既user\home\nacos\config\{serverName}_nacos\data\config-data-tenant\{group}\{dataId} 若本地有缓存,读取到了内容直接返回内容 后面一段代码 是读取加密的文本 ecnrypted ,封装的 ConfigResponse 传给了configFilterChainManager

若本地缓存没有,则远程读取

点击查看代码
try {
            ConfigResponse response = worker.getServerConfig(dataId, group, tenant, timeoutMs, false);
            cr.setContent(response.getContent());
            cr.setEncryptedDataKey(response.getEncryptedDataKey());
            configFilterChainManager.doFilter(null, cr);
            content = cr.getContent();
            
            return content;
        } catch (NacosException ioe) {
            if (NacosException.NO_RIGHT == ioe.getErrCode()) {
                throw ioe;
            }
            LOGGER.warn("[{}] [get-config] get from server error, dataId={}, group={}, tenant={}, msg={}",
                    worker.getAgentName(), dataId, group, tenant, ioe.toString());
        }

        content = LocalConfigInfoProcessor.getSnapshot(worker.getAgentName(), dataId, group, tenant);
        if (content != null) {
            LOGGER.warn("[{}] [get-config] get snapshot ok, dataId={}, group={}, tenant={}, config={}",
                    worker.getAgentName(), dataId, group, tenant, ContentUtils.truncateContent(content));
        }
        cr.setContent(content);
        String encryptedDataKey = LocalEncryptedDataKeyProcessor
                .getEncryptDataKeySnapshot(agent.getName(), dataId, group, tenant);
        cr.setEncryptedDataKey(encryptedDataKey);
        configFilterChainManager.doFilter(null, cr);
        content = cr.getContent();
        return content;
上面代码主要做两个事:
  • 远程获取文本
  • 本地生成文本快照

远程获取文本 worker 是在构造参数实例化的时候
this.worker = new ClientWorker(this.configFilterChainManager, serverListManager, clientProperties);
继续查看ClientWorker ,发现是由 ConfigRpcTransportClient agent 远程调用
this.agent.queryConfig(dataId, group, tenant, readTimeout, notify);
至此就获取到了远程配置文本信息

获取文本信息并添加监听getConfigAndSignListener

该方法就是获取远程文本,并监听信息的变化;

点击查看代码
public String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener)
            throws NacosException {
        group = StringUtils.isBlank(group) ? Constants.DEFAULT_GROUP : group.trim();
        ConfigResponse configResponse = worker.getAgent()
                .queryConfig(dataId, group, worker.getAgent().getTenant(), timeoutMs, false);
        String content = configResponse.getContent();
        String encryptedDataKey = configResponse.getEncryptedDataKey();
        worker.addTenantListenersWithContent(dataId, group, content, encryptedDataKey, Arrays.asList(listener));
        
        // get a decryptContent, fix https://github.com/alibaba/nacos/issues/7039
        ConfigResponse cr = new ConfigResponse();
        cr.setDataId(dataId);
        cr.setGroup(group);
        cr.setContent(content);
        cr.setEncryptedDataKey(encryptedDataKey);
        configFilterChainManager.doFilter(null, cr);
        return cr.getContent();
    }
查看代码可知 直接远程调用

ConfigResponse configResponse = worker.getAgent() .queryConfig(dataId, group, worker.getAgent().getTenant(), timeoutMs, false);
并添加一个监听
worker.addTenantListenersWithContent(dataId, group, content, encryptedDataKey, Arrays.asList(listener));
监听既把信息塞入一个缓存对象CacheData中用于监听管理

添加监听addListener

void addListener(String dataId, String group, Listener listener) throws NacosException;

点击查看代码
public void addTenantListeners(String dataId, String group, List<? extends Listener> listeners)
            throws NacosException {
        group = blank2defaultGroup(group);
        String tenant = agent.getTenant();
        CacheData cache = addCacheDataIfAbsent(dataId, group, tenant);
        synchronized (cache) {
            for (Listener listener : listeners) {
                cache.addListener(listener);
            }
            cache.setDiscard(false);
            cache.setSyncWithServer(false);
            agent.notifyListenConfig();
        }
        
    }

其他接口实现也都是类似的,如发布配置
boolean publishConfig(String dataId, String group, String content) throws NacosException;
boolean publishConfig(String dataId, String group, String content, String type) throws NacosException;

标签:dataId,group,String,nacos,client,content,源码,NacosException,throws
From: https://www.cnblogs.com/qlsem/p/17482442.html

相关文章

  • k8s驱逐篇(7)-kube-controller-manager驱逐-taintManager源码分析
    概述taintManager的主要功能为:当某个node被打上NoExecute污点后,其上面的pod如果不能容忍该污点,则taintManager将会驱逐这些pod,而新建的pod也需要容忍该污点才能调度到该node上;通过kcm启动参数--enable-taint-manager来确定是否启动taintManager,true时启动(启动参数默认值为true);k......
  • spring源码笔记
    Bean创建流程获取对象的BeanDefinition通过反射创建空对象填充属性调用init方法  Bean创建关键方法(按顺序)getBeandoGetBeancreateBeandoCreateBeancreateBeanInstancepopulateBean  解决循环依赖:三级缓存循环依赖原因单例,每个类只有一个对象。A引用B,B又......
  • XSSFClientAnchor 设置偏移无效 setDx setDy
    一、XSSFClientAnchor设置偏移无效setDxsetDy 原因是因为setDx,setDy所需要的x值y值并不是sheet.getColumnWidth(colNo)的值和row.getHeight()的值,而是需要进行一些转换。由于转换系数比较大,所以一般设个几百上千做测试基本是没反应,看起来就像没设置一样。这里先提供一下思......
  • nacos 基础使用
    依赖<!--配置中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--服务注册/发现--><dependency><groupId......
  • SpringCloud Alibaba入门3之nacos服务搭建
    我们继续在上一章的基础上学习。https://blog.51cto.com/u_13312531/6539601一、下载nacos-server从https://github.com/alibaba/nacos/releasesopeninnewwindow 下载nacos-server发行版。我们使用1.4.2版本二、启动nacos进入%path%\nacos\bin文件夹,执行cmd命令startup.cmd-m......
  • No Feign Client or loadBalanced defined
     创建consumer通过feign调用provider服务时报错一开始是Controller里@Autowired爆红,无法识别EchoService在主启动类中添加@EnableFeignClient后红线消失但运行后出现上面图中的错误百度一下后得知SpringCloudFeign在Hoxton.M2RELEASED版本之后不再使用ribbon(看的教程里教......
  • SPI的插件化设计-->JDK的SPI(ServiceLoader)实现拓展、实现Dubbo的SPI(ExtensionLoade
    (目录)1.什么是SPI?SPI的全称是ServiceProviderInterface,直译过来就是"服务提供接口",为了降低耦合,实现在模块装配的时候动态指定具体实现类的一种服务发现机制。动态地为接口寻找服务实现。它的核心来自于ServiceLoader这个类。javaSPI应用场景很广泛,在Java底层和一些......
  • 基于springboot+vue的漫画之家管理系统,附源码+数据库+论文+PPT,适合课程设计、毕业设计
    1、项目介绍随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代,“漫画之家”系统就是信息时代变革中的产物之一。任何系统都要遵循系统设计......
  • TVM 源码阅读PASS — VectorizeLoop
    本文地址:https://www.cnblogs.com/wanger-sjtu/p/17501119.htmlVectorizeLoop这个PASS就是对标记为ForKind::kVectorized的For循环做向量化处理,并对For循环中的语句涉及到的变量,替换为Ramp,以便于在Codegen的过程中生成相关的向量化运算的指令。VectorizeLoop这个PASS的入口函数......
  • ASP.NET DotnetLIMS系统全套源码
    LIMS系统功能包括:检测管理(合同管理、样品管理、样品收发管理、工作任务分配、检测结果登记、复核及审核、留样管理等)、报告管理(报告编制、审核、签发、打印等)、原始记录管理、仪器设备管理、消耗品管理、文件管理、组织人员管理、标准管理、客户供应商管理、查询统计、基础数据管理......