alibaba nacos源码分析

2 篇文章 0 订阅

1.启动客户端

配置中心客户端代码

import java.util.Properties;
import java.util.concurrent.Executor;
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;

/**
 * Config service example
 * sdk
 * @author Nacos
 *
 */
public class ConfigExample {

    public static void main(String[] args) throws NacosException, InterruptedException {
        String serverAddr = "localhost";
        String dataId = "example";
        String group = "DEFAULT_GROUP";
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        ConfigService configService = NacosFactory.createConfigService(properties);
        String content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);
        configService.addListener(dataId, group, new Listener() {
            @Override
            public void receiveConfigInfo(String configInfo) {
                System.out.println("recieve:" + configInfo);
            }

            @Override
            public Executor getExecutor() {
                return null;
            }
        });
        boolean isPublishOk = configService.publishConfig(dataId, group, "content");
        System.out.println(isPublishOk);

        Thread.sleep(3000);
        content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);
        boolean isRemoveOk = configService.removeConfig(dataId, group);
        System.out.println(isRemoveOk);
        Thread.sleep(3000);

        content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);
        Thread.sleep(300*1000);

    }
}

2.启动NacosConfigService

ConfigService configService = NacosFactory.createConfigService(properties)代码中
通过反射实例化NacosConfigService

public class ConfigFactory {
  ...
    public static ConfigService createConfigService(Properties properties) throws NacosException {
        try {
            Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.config.NacosConfigService");
            Constructor constructor = driverImplClass.getConstructor(Properties.class);
            ConfigService vendorImpl = (ConfigService)constructor.newInstance(properties);
            return vendorImpl;
        } catch (Throwable var4) {
            throw new NacosException(-400, var4);
        }
    }
    ...

构造方法中初始化参数及启动线程

public class NacosConfigService implements ConfigService {
    private static final Logger LOGGER = LogUtils.logger(NacosConfigService.class);
    private static final long POST_TIMEOUT = 3000L;
    private static final String EMPTY = "";
    private HttpAgent agent;
    private ClientWorker worker;
    private String namespace;
    private String encode;
    private ConfigFilterChainManager configFilterChainManager = new ConfigFilterChainManager();

    public NacosConfigService(Properties properties) throws NacosException {
        String encodeTmp = properties.getProperty("encode");
        if (StringUtils.isBlank(encodeTmp)) {
            this.encode = "UTF-8";
        } else {
            this.encode = encodeTmp.trim();
        }

        this.initNamespace(properties);
        this.agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
        this.agent.start();
        this.worker = new ClientWorker(this.agent, this.configFilterChainManager, properties);
    }

注册中心

MetricsHttpAgent 启动一个单线程的线程池,监听服务器中服务器地址
this.agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
this.agent.start();
会调用到com.alibaba.nacos.client.config.impl.ServerListManager#start

...
public synchronized void start() throws NacosException {
    if (!this.isStarted && !this.isFixed) {
        ServerListManager.GetServerListTask getServersTask = new ServerListManager.GetServerListTask(this.addressServerUrl);

        for(int i = 0; i < this.initServerlistRetryTimes && this.serverUrls.isEmpty(); ++i) {
            getServersTask.run();

            try {
                this.wait((long)(i + 1) * 100L);
            } catch (Exception var4) {
                LOGGER.warn("get serverlist fail,url: {}", this.addressServerUrl);
            }
        }

        if (this.serverUrls.isEmpty()) {
            LOGGER.error("[init-serverlist] fail to get NACOS-server serverlist! env: {}, url: {}", this.name, this.addressServerUrl);
            throw new NacosException(500, "fail to get NACOS-server serverlist! env:" + this.name + ", not connnect url:" + this.addressServerUrl);
        } else {
            TimerService.scheduleWithFixedDelay(getServersTask, 0L, 30L, TimeUnit.SECONDS);
            this.isStarted = true;
        }
    }
}
...

配置中心

this.worker = new ClientWorker(this.agent, this.configFilterChainManager, properties);
启动一个工作线程

ClientWorker 构造器

	...
    public ClientWorker(final HttpAgent agent, ConfigFilterChainManager configFilterChainManager, Properties properties) {
        this.agent = agent;
        this.configFilterChainManager = configFilterChainManager;
        this.init(properties);
        this.executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                t.setName("com.alibaba.nacos.client.Worker." + agent.getName());
                t.setDaemon(true);
                return t;
            }
        });
        this.executorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                t.setName("com.alibaba.nacos.client.Worker.longPolling." + agent.getName());
                t.setDaemon(true);
                return t;
            }
        });
        this.executor.scheduleWithFixedDelay(new Runnable() {
            public void run() {
                try {
                    ClientWorker.this.checkConfigInfo();
                } catch (Throwable var2) {
                    ClientWorker.LOGGER.error("[" + agent.getName() + "] [sub-check] rotate check error", var2);
                }

            }
        }, 1L, 10L, TimeUnit.MILLISECONDS);
    }
    ...

检查配置中心配置,如果配置信息超过默认指定大小(数据量过大)则会开启多个线程同时查询配置,每个线程查询指定数量配置(数据分段,多线程查询提高性能)

...
public void checkConfigInfo() {
     int listenerSize = ((Map)this.cacheMap.get()).size();
      int longingTaskCount = (int)Math.ceil((double)listenerSize / ParamUtil.getPerTaskConfigSize());
      if ((double)longingTaskCount > this.currentLongingTaskCount) {
          for(int i = (int)this.currentLongingTaskCount; i < longingTaskCount; ++i) {
              this.executorService.execute(new ClientWorker.LongPollingRunnable(i));
          }

          this.currentLongingTaskCount = (double)longingTaskCount;
      }

  }
  ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值