真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

NacosNamingService中selectOneHealthyInstance的原理及作用是什么

本篇內(nèi)容介紹了“NacosNamingService中selectOneHealthyInstance的原理及作用是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)建站主要從事成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)怒江州,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢(xún)建站服務(wù):18980820575

本文主要研究一下NacosNamingService的selectOneHealthyInstance

NacosNamingService

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

public class NacosNamingService implements NamingService {
    private static final String DEFAULT_PORT = "8080";
    private static final long DEFAULT_HEART_BEAT_INTERVAL = TimeUnit.SECONDS.toMillis(5);

    /**
     * Each Naming instance should have different namespace.
     */
    private String namespace;

    private String endpoint;

    private String serverList;

    private String cacheDir;

    private String logName;

    private HostReactor hostReactor;

    private BeatReactor beatReactor;

    private EventDispatcher eventDispatcher;

    private NamingProxy serverProxy;

    //......

    @Override
    public Instance selectOneHealthyInstance(String serviceName) throws NacosException {
        return selectOneHealthyInstance(serviceName, new ArrayList());
    }

    @Override
    public Instance selectOneHealthyInstance(String serviceName, String groupName) throws NacosException {
        return selectOneHealthyInstance(serviceName, groupName, true);
    }

    @Override
    public Instance selectOneHealthyInstance(String serviceName, boolean subscribe) throws NacosException {
        return selectOneHealthyInstance(serviceName, new ArrayList(), subscribe);
    }

    @Override
    public Instance selectOneHealthyInstance(String serviceName, String groupName, boolean subscribe) throws NacosException {
        return selectOneHealthyInstance(serviceName, groupName, new ArrayList(), subscribe);
    }

    @Override
    public Instance selectOneHealthyInstance(String serviceName, List clusters) throws NacosException {
        return selectOneHealthyInstance(serviceName, clusters, true);
    }

    @Override
    public Instance selectOneHealthyInstance(String serviceName, String groupName, List clusters) throws NacosException {
        return selectOneHealthyInstance(serviceName, groupName, clusters, true);
    }

    @Override
    public Instance selectOneHealthyInstance(String serviceName, List clusters, boolean subscribe)
        throws NacosException {
        return selectOneHealthyInstance(serviceName, Constants.DEFAULT_GROUP, clusters, subscribe);
    }

    @Override
    public Instance selectOneHealthyInstance(String serviceName, String groupName, List clusters, boolean subscribe) throws NacosException {

        if (subscribe) {
            return Balancer.RandomByWeight.selectHost(
                hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ",")));
        } else {
            return Balancer.RandomByWeight.selectHost(
                hostReactor.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ",")));
        }
    }

    //......
}
  • selectOneHealthyInstance跟selectInstances類(lèi)似,只不過(guò)它返回的是單個(gè)instance;selectOneHealthyInstance也是先從hostReactor獲取serviceInfo

  • 如果subscribe為true,則執(zhí)行hostReactor.getServiceInfo獲取serviceInfo,否則執(zhí)行hostReactor.getServiceInfoDirectlyFromServer獲取serviceInfo

  • 獲取到serviceInfo之后,selectOneHealthyInstance通過(guò)Balancer.RandomByWeight.selectHost方法來(lái)選取單個(gè)healthy的instance

Balancer

nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/naming/core/Balancer.java

public class Balancer {

    /**
     * report status to server
     */
    public final static List UNCONSISTENT_SERVICE_WITH_ADDRESS_SERVER = new CopyOnWriteArrayList();

    public static class RandomByWeight {

        public static List selectAll(ServiceInfo serviceInfo) {
            List hosts = serviceInfo.getHosts();

            if (CollectionUtils.isEmpty(hosts)) {
                throw new IllegalStateException("no host to srv for serviceInfo: " + serviceInfo.getName());
            }

            return hosts;
        }

        public static Instance selectHost(ServiceInfo dom) {

            List hosts = selectAll(dom);

            if (CollectionUtils.isEmpty(hosts)) {
                throw new IllegalStateException("no host to srv for service: " + dom.getName());
            }

            return getHostByRandomWeight(hosts);
        }
    }

    /**
     * Return one host from the host list by random-weight.
     *
     * @param hosts The list of the host.
     * @return The random-weight result of the host
     */
    protected static Instance getHostByRandomWeight(List hosts) {
        NAMING_LOGGER.debug("entry randomWithWeight");
        if (hosts == null || hosts.size() == 0) {
            NAMING_LOGGER.debug("hosts == null || hosts.size() == 0");
            return null;
        }

        Chooser vipChooser = new Chooser("www.taobao.com");

        NAMING_LOGGER.debug("new Chooser");

        List> hostsWithWeight = new ArrayList>();
        for (Instance host : hosts) {
            if (host.isHealthy()) {
                hostsWithWeight.add(new Pair(host, host.getWeight()));
            }
        }
        NAMING_LOGGER.debug("for (Host host : hosts)");
        vipChooser.refresh(hostsWithWeight);
        NAMING_LOGGER.debug("vipChooser.refresh");
        return vipChooser.randomWithWeight();
    }
}
  • Balancer的RandomByWeight提供了selectAll及selectHost方法;selectAll針對(duì)serviceInfo.getHosts()進(jìn)行了空判斷,空的話(huà)會(huì)拋出IllegalStateException

  • selectHost方法內(nèi)部調(diào)用了selectAll方法,其最后通過(guò)getHostByRandomWeight來(lái)選取單個(gè)healthy的instance

  • getHostByRandomWeight方法首先創(chuàng)建一個(gè)Chooser,然后選取healthy的instance構(gòu)造hostsWithWeight,再通過(guò)vipChooser.refresh(hostsWithWeight)進(jìn)行refresh,最后通過(guò)vipChooser.randomWithWeight()選取單個(gè)healthy的instance

Chooser

nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/naming/utils/Chooser.java

public class Chooser {

    private K uniqueKey;

    private volatile Ref ref;

    public T random() {
        List items = ref.items;
        if (items.size() == 0) {
            return null;
        }
        if (items.size() == 1) {
            return items.get(0);
        }
        return items.get(ThreadLocalRandom.current().nextInt(items.size()));
    }

    public T randomWithWeight() {
        Ref ref = this.ref;
        double random = ThreadLocalRandom.current().nextDouble(0, 1);
        int index = Arrays.binarySearch(ref.weights, random);
        if (index < 0) {
            index = -index - 1;
        } else {
            return ref.items.get(index);
        }

        if (index >= 0 && index < ref.weights.length) {
            if (random < ref.weights[index]) {
                return ref.items.get(index);
            }
        }

        /* This should never happen, but it ensures we will return a correct
         * object in case there is some floating point inequality problem
         * wrt the cumulative probabilities. */
        return ref.items.get(ref.items.size() - 1);
    }

    public Chooser(K uniqueKey) {
        this(uniqueKey, new ArrayList>());
    }

    public Chooser(K uniqueKey, List> pairs) {
        Ref ref = new Ref(pairs);
        ref.refresh();
        this.uniqueKey = uniqueKey;
        this.ref = ref;
    }

    public K getUniqueKey() {
        return uniqueKey;
    }

    public Ref getRef() {
        return ref;
    }

    public void refresh(List> itemsWithWeight) {
        Ref newRef = new Ref(itemsWithWeight);
        newRef.refresh();
        newRef.poller = this.ref.poller.refresh(newRef.items);
        this.ref = newRef;
    }

    //......
}
  • Chooser的refresh方法會(huì)根據(jù)itemsWithWeight創(chuàng)建Ref,然后執(zhí)行Ref的refresh方法;randomWithWeight方法通過(guò)Arrays.binarySearch(ref.weights, random)創(chuàng)建初始index,然后根據(jù)index從ref.items獲取元素

Ref

nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/naming/utils/Chooser.java

    public class Ref {
        private List> itemsWithWeight = new ArrayList>();
        private List items = new ArrayList();
        private Poller poller = new GenericPoller(items);
        private double[] weights;

        @SuppressWarnings("unchecked")
        public Ref(List> itemsWithWeight) {
            this.itemsWithWeight = itemsWithWeight;
        }

        public void refresh() {
            Double originWeightSum = (double) 0;

            for (Pair item : itemsWithWeight) {

                double weight = item.weight();
                //ignore item which weight is zero.see test_randomWithWeight_weight0 in ChooserTest
                if (weight <= 0) {
                    continue;
                }

                items.add(item.item());
                if (Double.isInfinite(weight)) {
                    weight = 10000.0D;
                }
                if (Double.isNaN(weight)) {
                    weight = 1.0D;
                }
                originWeightSum += weight;
            }

            double[] exactWeights = new double[items.size()];
            int index = 0;
            for (Pair item : itemsWithWeight) {
                double singleWeight = item.weight();
                //ignore item which weight is zero.see test_randomWithWeight_weight0 in ChooserTest
                if (singleWeight <= 0) {
                    continue;
                }
                exactWeights[index++] = singleWeight / originWeightSum;
            }

            weights = new double[items.size()];
            double randomRange = 0D;
            for (int i = 0; i < index; i++) {
                weights[i] = randomRange + exactWeights[i];
                randomRange += exactWeights[i];
            }

            double doublePrecisionDelta = 0.0001;

            if (index == 0 || (Math.abs(weights[index - 1] - 1) < doublePrecisionDelta)) {
                return;
            }
            throw new IllegalStateException("Cumulative Weight caculate wrong , the sum of probabilities does not equals 1.");
        }

        //......
    }
  • Ref的refresh方法主要是初始化items及weights

小結(jié)

  • selectOneHealthyInstance跟selectInstances類(lèi)似,只不過(guò)它返回的是單個(gè)instance;selectOneHealthyInstance也是先從hostReactor獲取serviceInfo

  • 如果subscribe為true,則執(zhí)行hostReactor.getServiceInfo獲取serviceInfo,否則執(zhí)行hostReactor.getServiceInfoDirectlyFromServer獲取serviceInfo

  • 獲取到serviceInfo之后,selectOneHealthyInstance通過(guò)Balancer.RandomByWeight.selectHost方法來(lái)選取單個(gè)healthy的instance

“NacosNamingService中selectOneHealthyInstance的原理及作用是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


當(dāng)前標(biāo)題:NacosNamingService中selectOneHealthyInstance的原理及作用是什么
文章出自:http://weahome.cn/article/gcgicc.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部