1. 程式人生 > 程式設計 >聊聊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: {},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 {}",serverUrls);
    }

    private List<String> getApacheServerList(String url,String name) {
        try {
            HttpResult httpResult = HttpSimpleClient.httpGet(url,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

doc