中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

nacos NamingProxy中getServiceList的原理及用法

發布時間:2021-06-26 14:45:58 來源:億速云 閱讀:302 作者:chen 欄目:大數據

本篇內容主要講解“nacos NamingProxy中getServiceList的原理及用法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“nacos NamingProxy中getServiceList的原理及用法”吧!

本文主要研究一下nacos NamingProxy的getServiceList

NamingProxy.initRefreshSrvIfNeed

nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java

public class NamingProxy {

    private static final int DEFAULT_SERVER_PORT = 8848;

    private int serverPort = DEFAULT_SERVER_PORT;

    private String namespaceId;

    private String endpoint;

    private String nacosDomain;

    private List<String> serverList;

    private List<String> serversFromEndpoint = new ArrayList<String>();

    private long lastSrvRefTime = 0L;

    private long vipSrvRefInterMillis = TimeUnit.SECONDS.toMillis(30);

    private Properties properties;

    public NamingProxy(String namespaceId, String endpoint, String serverList) {

        this.namespaceId = namespaceId;
        this.endpoint = endpoint;
        if (StringUtils.isNotEmpty(serverList)) {
            this.serverList = Arrays.asList(serverList.split(","));
            if (this.serverList.size() == 1) {
                this.nacosDomain = serverList;
            }
        }

        initRefreshSrvIfNeed();
    }

    private void initRefreshSrvIfNeed() {
        if (StringUtils.isEmpty(endpoint)) {
            return;
        }

        ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                t.setName("com.alibaba.nacos.client.naming.serverlist.updater");
                t.setDaemon(true);
                return t;
            }
        });

        executorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                refreshSrvIfNeed();
            }
        }, 0, vipSrvRefInterMillis, TimeUnit.MILLISECONDS);

        refreshSrvIfNeed();
    }

    //......

    private void refreshSrvIfNeed() {
        try {

            if (!CollectionUtils.isEmpty(serverList)) {
                NAMING_LOGGER.debug("server list provided by user: " + serverList);
                return;
            }

            if (System.currentTimeMillis() - lastSrvRefTime < vipSrvRefInterMillis) {
                return;
            }

            List<String> list = getServerListFromEndpoint();

            if (CollectionUtils.isEmpty(list)) {
                throw new Exception("Can not acquire Nacos list");
            }

            if (!CollectionUtils.isEqualCollection(list, serversFromEndpoint)) {
                NAMING_LOGGER.info("[SERVER-LIST] server list is updated: " + list);
            }

            serversFromEndpoint = list;
            lastSrvRefTime = System.currentTimeMillis();
        } catch (Throwable e) {
            NAMING_LOGGER.warn("failed to update server list", e);
        }
    }

    public List<String> getServerListFromEndpoint() {

        try {
            String urlString = "http://" + endpoint + "/nacos/serverlist";
            List<String> headers = builderHeaders();

            HttpClient.HttpResult result = HttpClient.httpGet(urlString, headers, null, UtilAndComs.ENCODING);
            if (HttpURLConnection.HTTP_OK != result.code) {
                throw new IOException("Error while requesting: " + urlString + "'. Server returned: "
                    + result.code);
            }

            String content = result.content;
            List<String> list = new ArrayList<String>();
            for (String line : IoUtils.readLines(new StringReader(content))) {
                if (!line.trim().isEmpty()) {
                    list.add(line.trim());
                }
            }

            return list;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    //......
}
  • NamingProxy的構造器執行了initRefreshSrvIfNeed方法,該方法在endpoint不為空的時候,會注冊一個定時任務,每隔vipSrvRefInterMillis時間執行一次refreshSrvIfNeed方法,同時立馬調用了refreshSrvIfNeed方法

  • refreshSrvIfNeed方法在serverList為空,且距離lastSrvRefTime大于等于vipSrvRefInterMillis時會通過getServerListFromEndpoint()方法獲取serverList更新serversFromEndpoint及lastSrvRefTime

  • getServerListFromEndpoint方法會向endpoint請求/serverlist接口,獲取server端返回的serverList

NamingProxy.getServiceList

nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java

public class NamingProxy {

    private static final int DEFAULT_SERVER_PORT = 8848;

    private int serverPort = DEFAULT_SERVER_PORT;

    private String namespaceId;

    private String endpoint;

    private String nacosDomain;

    private List<String> serverList;

    private List<String> serversFromEndpoint = new ArrayList<String>();

    private long lastSrvRefTime = 0L;

    private long vipSrvRefInterMillis = TimeUnit.SECONDS.toMillis(30);

    private Properties properties;

    //......

    public ListView<String> getServiceList(int pageNo, int pageSize, String groupName) throws NacosException {
        return getServiceList(pageNo, pageSize, groupName, null);
    }

    public ListView<String> getServiceList(int pageNo, int pageSize, String groupName, AbstractSelector selector) throws NacosException {

        Map<String, String> params = new HashMap<String, String>(4);
        params.put("pageNo", String.valueOf(pageNo));
        params.put("pageSize", String.valueOf(pageSize));
        params.put(CommonParams.NAMESPACE_ID, namespaceId);
        params.put(CommonParams.GROUP_NAME, groupName);

        if (selector != null) {
            switch (SelectorType.valueOf(selector.getType())) {
                case none:
                    break;
                case label:
                    ExpressionSelector expressionSelector = (ExpressionSelector) selector;
                    params.put("selector", JSON.toJSONString(expressionSelector));
                    break;
                default:
                    break;
            }
        }

        String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/service/list", params);

        JSONObject json = JSON.parseObject(result);
        ListView<String> listView = new ListView<String>();
        listView.setCount(json.getInteger("count"));
        listView.setData(JSON.parseObject(json.getString("doms"), new TypeReference<List<String>>() {
        }));

        return listView;
    }

    public String reqAPI(String api, Map<String, String> params) throws NacosException {

        List<String> snapshot = serversFromEndpoint;
        if (!CollectionUtils.isEmpty(serverList)) {
            snapshot = serverList;
        }

        return reqAPI(api, params, snapshot);
    }

    public String reqAPI(String api, Map<String, String> params, List<String> servers) {
        return reqAPI(api, params, servers, HttpMethod.GET);
    }

    public String reqAPI(String api, Map<String, String> params, List<String> servers, String method) {

        params.put(CommonParams.NAMESPACE_ID, getNamespaceId());

        if (CollectionUtils.isEmpty(servers) && StringUtils.isEmpty(nacosDomain)) {
            throw new IllegalArgumentException("no server available");
        }

        Exception exception = new Exception();

        if (servers != null && !servers.isEmpty()) {

            Random random = new Random(System.currentTimeMillis());
            int index = random.nextInt(servers.size());

            for (int i = 0; i < servers.size(); i++) {
                String server = servers.get(index);
                try {
                    return callServer(api, params, server, method);
                } catch (NacosException e) {
                    exception = e;
                    NAMING_LOGGER.error("request {} failed.", server, e);
                } catch (Exception e) {
                    exception = e;
                    NAMING_LOGGER.error("request {} failed.", server, e);
                }

                index = (index + 1) % servers.size();
            }

            throw new IllegalStateException("failed to req API:" + api + " after all servers(" + servers + ") tried: "
                + exception.getMessage());
        }

        for (int i = 0; i < UtilAndComs.REQUEST_DOMAIN_RETRY_COUNT; i++) {
            try {
                return callServer(api, params, nacosDomain);
            } catch (Exception e) {
                exception = e;
                NAMING_LOGGER.error("[NA] req api:" + api + " failed, server(" + nacosDomain, e);
            }
        }

        throw new IllegalStateException("failed to req API:/api/" + api + " after all servers(" + servers + ") tried: "
            + exception.getMessage());

    }
                
    //......
}
  • getServiceList方法有個AbstractSelector參數,它會往請求的參數里頭添加selector參數,目前label類型會添加ExpressionSelector,之后調用reqAPI方法請求/service/list接口

  • reqAPI方法首先將serversFromEndpoint賦值給snapshot,但是serverList不為空的情況下會重置snapshot為serverList,然后進行reqAPI請求

  • reqAPI方法會根據servers.size()隨機一個index,然后以servers.size()為最大循環次數開始for循環,循環里頭根據index獲取server然后通過callServer請求,請求成功則跳出循環返回,請求失敗則遞增index并對servers.size()取余繼續下次循環,如果都請求失敗則最后拋出IllegalStateException

小結

  • NamingProxy的構造器執行了initRefreshSrvIfNeed方法,該方法在endpoint不為空的時候,會注冊一個定時任務,每隔vipSrvRefInterMillis時間執行一次refreshSrvIfNeed方法

  • refreshSrvIfNeed方法在serverList為空,且距離lastSrvRefTime大于等于vipSrvRefInterMillis時會通過getServerListFromEndpoint()方法獲取serverList更新serversFromEndpoint及lastSrvRefTime

  • getServiceList方法優先以serverList作為server端地址列表,如果它為空再以serversFromEndpoint為準,然后通過reqAPI方法請求的時候,隨機選擇一個server進行請求,最多請求server.size()次,請求成功則跳出循環返回,請求失敗則遞增index并對servers.size()取余繼續下次循環,如果都請求失敗則最后拋出IllegalStateException

到此,相信大家對“nacos NamingProxy中getServiceList的原理及用法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

临江市| 夏邑县| 汝阳县| 西宁市| 五原县| 威远县| 铜陵市| 吉隆县| 阳泉市| 普安县| 桦川县| 邛崃市| 襄垣县| 安达市| 平阳县| 霍邱县| 盐城市| 南川市| 石屏县| 镇原县| 山阳县| 太白县| 潼关县| 灵台县| 广州市| 白朗县| 松阳县| 奉节县| 巨野县| 包头市| 皋兰县| 明溪县| 望城县| 清苑县| 天峻县| 武城县| 崇文区| 嵩明县| 虹口区| 泸西县| 鄯善县|