专栏首页码匠的流水账聊聊nacos client的ServerListManager的start

聊聊nacos client的ServerListManager的start

本文主要研究一下nacos client的ServerListManager的start

ServerListManager

nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java

public class ServerListManager {

    private static final Logger LOGGER = LogUtils.logger(ServerListManager.class);
    private static final String HTTPS = "https://";
    private static final String HTTP = "http://";

    //......

    public synchronized void start() throws NacosException {

        if (isStarted || isFixed) {
            return;
        }

        GetServerListTask getServersTask = new GetServerListTask(addressServerUrl);
        for (int i = 0; i < initServerlistRetryTimes && serverUrls.isEmpty(); ++i) {
            getServersTask.run();
            try {
                this.wait((i + 1) * 100L);
            } catch (Exception e) {
                LOGGER.warn("get serverlist fail,url: {}", addressServerUrl);
            }
        }

        if (serverUrls.isEmpty()) {
            LOGGER.error("[init-serverlist] fail to get NACOS-server serverlist! env: {}, url: {}", name,
                addressServerUrl);
            throw new NacosException(NacosException.SERVER_ERROR,
                "fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl);
        }

        TimerService.scheduleWithFixedDelay(getServersTask, 0L, 30L, TimeUnit.SECONDS);
        isStarted = true;
    }

    //......
}
  • ServerListManager的start方法在非isStarted且非isFixed的条件下会执行GetServerListTask,失败重试次数为initServerlistRetryTimes,如果serverUrls为空则抛出NacosException;如果不为空则注册该getServersTask每隔30秒执行一次来刷新server list

GetServerListTask

nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java

public class ServerListManager {

//......

    class GetServerListTask implements Runnable {
        final String url;

        GetServerListTask(String url) {
            this.url = url;
        }

        @Override
        public void run() {
            /**
             * get serverlist from nameserver
             */
            try {
                updateIfChanged(getApacheServerList(url, name));
            } catch (Exception e) {
                LOGGER.error("[" + name + "][update-serverlist] failed to update serverlist from address server!",
                    e);
            }
        }
    }

    private void updateIfChanged(List<String> newList) {
        if (null == newList || newList.isEmpty()) {
            LOGGER.warn("[update-serverlist] current serverlist from address server is empty!!!");
            return;
        }

        List<String> newServerAddrList = new ArrayList<String>();
        for (String server : newList) {
            if (server.startsWith(HTTP) || server.startsWith(HTTPS)) {
                newServerAddrList.add(server);
            } else {
                newServerAddrList.add(HTTP + server);
            }
        }

        /**
         * no change
         */
        if (newServerAddrList.equals(serverUrls)) {
            return;
        }
        serverUrls = new ArrayList<String>(newServerAddrList);
        iterator = iterator();
        currentServerAddr = iterator.next();

        EventDispatcher.fireEvent(new ServerlistChangeEvent());
        LOGGER.info("[{}] [update-serverlist] serverlist updated to {}", name, serverUrls);
    }

    private List<String> getApacheServerList(String url, String name) {
        try {
            HttpResult httpResult = HttpSimpleClient.httpGet(url, null, null, null, 3000);

            if (HttpURLConnection.HTTP_OK == httpResult.code) {
                if (DEFAULT_NAME.equals(name)) {
                    EnvUtil.setSelfEnv(httpResult.headers);
                }
                List<String> lines = IOUtils.readLines(new StringReader(httpResult.content));
                List<String> result = new ArrayList<String>(lines.size());
                for (String serverAddr : lines) {
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(serverAddr)) {
                        String[] ipPort = serverAddr.trim().split(":");
                        String ip = ipPort[0].trim();
                        if (ipPort.length == 1) {
                            result.add(ip + ":" + ParamUtil.getDefaultServerPort());
                        } else {
                            result.add(serverAddr);
                        }
                    }
                }
                return result;
            } else {
                LOGGER.error("[check-serverlist] error. addressServerUrl: {}, code: {}", addressServerUrl,
                    httpResult.code);
                return null;
            }
        } catch (IOException e) {
            LOGGER.error("[check-serverlist] exception. url: " + url, e);
            return null;
        }
    }

    //......
}
  • GetServerListTask实现了Runnable接口,其run方法会通过getApacheServerList请求addressServerUrl获取服务端地址列表,然后执行updateIfChanged方法;该方法会判断server list是否有变更,有变更则更新serverUrls,然后发布ServerlistChangeEvent

小结

ServerListManager的start方法在非isStarted且非isFixed的条件下会执行GetServerListTask,失败重试次数为initServerlistRetryTimes,如果serverUrls为空则抛出NacosException;如果不为空则注册该getServersTask每隔30秒执行一次来刷新server list

本文分享自微信公众号 - 码匠的流水账(geek_luandun),作者:码匠乱炖

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊聊nacos client的ServerListManager的start

    本文主要研究一下nacos client的ServerListManager的start

    codecraft
  • 聊聊NacosNamingService的subscribe及unsubscribe

    本文主要研究一下NacosNamingService的subscribe及unsubscribe

    codecraft
  • 聊聊artemis的ServerConnectionLifeCycleListener

    本文主要研究一下artemis的ServerConnectionLifeCycleListener

    codecraft
  • 聊聊nacos client的ServerListManager的start

    本文主要研究一下nacos client的ServerListManager的start

    codecraft
  • ELK学习笔记之Logstash详解

    官方介绍:Logstash is an open source data collection engine with real-time pipelining...

    Jetpropelledsnake21
  • sshd服务搭建与管理

    SSH(Secure Shell)建立在应用层和传输层基础上的安全协议。它使用加密验证来确认用户身份,并对两台主机之间的所有通信加密。

    用户1679793
  • django form使用

    在django中,可以使用form来进行表单验证,甚至自动生成样式(虽然不怎么好看)

    超级大猪
  • 权限管理su、sudo、限制root远程登录 原

    语法: su [-] username “-”可有可无,加上“-”的作用是在切换用户时初始化当前用户的各种环境变量。普通用户su不加username时就是直...

    阿dai学长
  • 学界 | 一窥 ACL 2018 最佳论文

    AI 科技评论按:随着定于 7 月 15 日的开会日期逐渐临近,自然语言处理顶会 ACL 2018 继公开了接收论文名单之后,今天也公布了包含 3 篇长论文 与...

    AI科技评论
  • URI 源码分析

    java404

扫码关注云+社区

领取腾讯云代金券