ÀÖÓãµç¾º

  • ½ÌÓýÐÐÒµA¹ÉIPOµÚÒ»¹É£¨¹ÉƱ´úÂë 003032£©

    È«¹ú×Éѯ/ͶËßÈÈÏߣº400-618-4000

    RibbonµÄ³£ÓøºÔؾùºâ²ßÂÔÏêϸ·ÖÎö¡¾¼¼Êõ¸É»õ¡¿

    ¸üÐÂʱ¼ä:2021Äê03ÔÂ26ÈÕ13ʱ53·Ö À´Ô´:ÀÖÓãµç¾º ä¯ÀÀ´ÎÊý:

    ºÃ¿Ú±®ITÅàѵ



    1.Ribbon½éÉÜ

    ÒòΪ΢·þÎñÊÇĿǰ»¥ÁªÍø¹«Ë¾±È½ÏÁ÷Ðеļܹ¹£¬ËùÒÔspring¾ÍÌṩÁËÒ»¸ö¶¥¼¶¿ò¼Ü-spring cloud£¬À´½â¾öÎÒÃÇÔÚ¿ª·¢Î¢·þÎñ¼Ü¹¹ÖÐÓöµ½µÄ¸÷ÖÖ¸÷ÑùµÄÎÊÌ⣬½ñÌìµÄÖ÷½ÇÊÇspring cloud ¿ò¼ÜÖм¯³ÉµÄ×é¼þRibbon£¬ÄÇôRibbonÄܽâ¾öʲôÎÊÌâÄØ£¬ÎÒÃÇÀ´Ë¼¿¼ÏÂÃæµÄÎÊÌâ¡£

    ΢·þÎñ¼Ü¹¹ÖеÄÿ¸ö·þÎñΪÁ˸߿ÉÓ㬺ܴó³Ì¶ÈÉ϶¼»á½øÐм¯Èº£¬ÎÒÃǼÙÉèÏÖÔÚ¼¯ÈºÁË3¸öuser·þÎñ£¬Í¬Ê±ÄÜÌṩÏàͬµÄ·þÎñ£¬ÎÊÌâÀ´ÁË£¬ÎÒÃÇÈçºÎ¾ö¶¨µ÷ÓÃÕâ3¸öuser·þÎñÖеÄÄÄÒ»¸öÄØ£¿

    ¸ù¾Ý²»Í¬·ÖÎö½Ç¶È£¬»áÓв»Í¬µÄ´ð°¸£¬Ò²¿ÉÒÔÀí½âΪ¸ù¾Ý²»Í¬µÄÇé¿ö£¬ÎÒÃÇ¿ÉÒÔд²»Í¬µÄËã·¨£¬À´¾ö¶¨µ½µ×´Ëʱ´Ë¿Ì£¬µ÷ÓÃÕâ3¸öuser·þÎñµÄÄÄÒ»¸ö£¬ÄÇô£¬Ribbon¾Í¸øÎÒÃÇÌṩÁ˲»Í¬µÄËã·¨£¬ÎÒÃÇ¿ÉÒÔ¸ù¾ÝÒµÎñ³¡¾°£¬µ÷ÕûÅäÖÃÎļþ£¬¾ö¶¨µ½µ×ʹÓÃÄĸöËã·¨£¬ÕâÑù£¬Ëã·¨ÖÐ¾Í»á¼ÆËã³öµ÷ÓÃÄĸöuser·þÎñÁË¡£

    2.×¼±¸¹¤×÷

    1£©ÎÒÃÇ×¼±¸Ò»¸öeureka×¢²áÖÐÐÄ

    2£©ÔÙ×¼±¸Ò»¸öorder·þÎñ

    3£©ÔÙ×¼±¸3¸öÏàͬ´úÂëµÄuser·þÎñ£¬ÕâÑù£¬order·þÎñͨ¹ýeureka×¢²áÖÐÐÄ£¬¾Í¿ÉÒÔ·¢ÏÖuserµÄ3¸ö·þÎñ

    3.RibbonµÄ³£ÓøºÔؾùºâ²ßÂÔ

    RibbonÊÇͨ¹ýIRuleµÄÕâ¸ö½Ó¿ÚÀ´Ñ¡Ôñ3¸öuser·þÎñÖеÄÄĸöµÄ£¬µ«ÊÇʵ¼ÊÖ´ÐеĴúÂë¿Ï¶¨ÊǼ̳ÐÁËÕâ¸ö½Ó¿ÚµÄʵÏÖÀ࣬ËùÒÔÑ¡Ôñ²»Í¬µÄʵÏÖÀ࣬¾Í»áÑ¡Ôñ²»Í¬¸ºÔؾùºâ²ßÂÔ

    public interface IRule {
        
        Server choose(Object var1);
    
        void setLoadBalancer(ILoadBalancer var1);
    
        ILoadBalancer getLoadBalancer();
    }

    3.1. RoundRobinRule  ÂÖѯ²ßÂÔ

    ´Ë²ßÂÔÊÇRibbonµÄĬÈϲßÂÔ£¬Êǰ´ÕÕ˳Ðò£¬ÒÀ´Î¶ÔËùÓеÄuser·þÎñ½øÐзÃÎÊ¡£

    ͨ¹ýÖØÐ´IRuleµÄchoose·½·¨£¬À´Ñ¡Ôñ²¢·µ»Ø¾ö¶¨µ÷ÓõÄuser·þÎñ£¬ÔÚÏÂÃæµÄÔ´ÂëÖУ¬List allServers = lb.getAllServers(); »ñµÃÁËËùÓеÄ3¸öuser·þÎñʵÀý£¬int nextServerIndex = this.incrementAndGetModulo(serverCount); ±£´æÁ˵±Ç°µ÷ÓõÄuserʵÀýµÄÐòºÅ£¬È»ºó¾Í¿ÉÒÔ°´ÕÕ˳Ðòµ÷ÓÃÏÂÒ»¸öuser·þÎñÁË

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        } else {
            Server server = null;
            int count = 0;
    
            while(true) {
                if (server == null && count++ < 10) {
                    List<Server> reachableServers = lb.getReachableServers();
                    List<Server> allServers = lb.getAllServers();
                    int upCount = reachableServers.size();
                    //×Ü·þÎñʵÀýÊýÁ¿
                    int serverCount = allServers.size();
                    if (upCount != 0 && serverCount != 0) {
                        int nextServerIndex = this.incrementAndGetModulo(serverCount);
                        server = (Server)allServers.get(nextServerIndex);
                        if (server == null) {
                            Thread.yield();
                        } else {
                            if (server.isAlive() && server.isReadyToServe()) {
                                return server;
                            }
    
                            server = null;
                        }
                        continue;
                    }
    
                    log.warn("No up servers available from load balancer: " + lb);
                    return null;
                }
    
                if (count >= 10) {
                    log.warn("No available alive servers after 10 tries from load balancer: " + lb);
                }
    
                return server;
            }
        }
    }

    debugµÄͼÀý£º

    µÚÒ»´Î·ÃÎÊ£º·ÃÎʵÄÊǵÚÒ»¸öʵÀý

    1616729974058_01.png

    µÚ¶þ´Î·ÃÎÊ£º·ÃÎʵÄÊǵڶþ¸öʵÀý

    1616730000374_02.png

    3.2. RoundRobinRule  Ëæ»ú²ßÂÔ

    ¾ÍºÍÕâ¸ö²ßÂÔµÄÃû×ÖÒ»Ñù£¬ÊǶÔuserµÄ3¸ö·þÎñµÄËæ»úµ÷Óã¬ËùÒÔ²»´æÔÚ¹æÂÉ£¬ÈçÏÂÔ´ÂëÖÐint index = this.chooseRandomInt(serverCount); ͨ¹ýËæ»úÊýÀ´Ñ¡Ôñϱ꣬ËùÒÔ¶Ôuser·þÎñµÄµ÷ÓÃÊÇËæ»úµÄ

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        } else {
            Server server = null;
    
            while(server == null) {
                if (Thread.interrupted()) {
                    return null;
                }
    
                List<Server> upList = lb.getReachableServers();
                List<Server> allList = lb.getAllServers();
                int serverCount = allList.size();
                if (serverCount == 0) {
                    return null;
                }
    
                int index = this.chooseRandomInt(serverCount);
                server = (Server)upList.get(index);
                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {
                        return server;
                    }
    
                    server = null;
                    Thread.yield();
                }
            }
    
            return server;
        }
    }

    debugµÄͼÀý£º

    µÚÒ»´Î·ÃÎÊ£º·ÃÎʵÄÊǵÚÒ»¸öʵÀý

    1616730026639_03.png

    µÚ¶þ´Î·ÃÎÊ£º·ÃÎʵϹÊǵÚÒ»¸öʵÀý

    1616730049712_04.png

    µÚÈý´Î·ÃÎÊ£º·ÃÎʵÄÊǵÚÈý¸öʵÀý

    undefined

    3.3. WeightedResponseTimeRuleÏìӦʱ¼ä¼ÓÈ¨ÖØ²ßÂÔ

    ¸ù¾ÝuserµÄ3¸ö·þÎñµÄÏìӦʱ¼äÀ´·ÖÅäÈ¨ÖØ£¬ÏìӦʱ¼äÔ½³¤µÄ·þÎñ£¬È¨ÖØÔ½µÍ£¬ÄÇô±»µ÷ÓõĸÅÂÊÒ²¾ÍÔ½µÍ¡£Ïà·´£¬ÏìӦʱ¼äÔ½¶ÌµÄ·þÎñ£¬È¨ÖØÔ½¸ß£¬±»µ÷ÓõĸÅÂÊÒ²¾ÍÔ½¸ß

    ÏìӦʱ¼ä¼ÓÈ¨ÖØ²ßÂÔµÄʵÏÖ·ÖΪÁ½²½£º

    1. WeightedResponseTimeRuleʵÏÖÀàÖÐĬÈÏÇé¿öÏÂÿ¸ô30Ãë»áͳ¼ÆÒ»´Îÿ¸ö·þÎñµÄÈ¨ÖØ£¬ÔÚ´Ë30ÃëÄÚ£¬ÓõÄÊÇÂÖѯ²ßÂÔ
    2. 30ÃëÖ®ºó£¬»á¸ù¾Ýͳ¼ÆµÄ½á¹ûÀ´·ÖÅäÿ¸öʵÀýµÄÈ¨ÖØ£¬È»ºó¸ù¾ÝÈ¨ÖØÀ´·ÖÅäµ÷ÓôÎÊý
    extends RoundRobinRule
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        } else {
            Server server = null;
    
            while(server == null) {
                List<Double> currentWeights = this.accumulatedWeights;
                if (Thread.interrupted()) {
                    return null;
                }
    
                List<Server> allList = lb.getAllServers();
                int serverCount = allList.size();
                if (serverCount == 0) {
                    return null;
                }
    
                int serverIndex = 0;
                double maxTotalWeight = currentWeights.size() == 0 ? 0.0D : (Double)currentWeights.get(currentWeights.size() - 1);
                //ÔÚ30ÃëÖ®ÄÚ£¬maxTotalWeight±äÁ¿»áÒ»Ö±ÊÇ0.0
                if (maxTotalWeight >= 0.001D && serverCount == currentWeights.size()) {
                    double randomWeight = this.random.nextDouble() * maxTotalWeight;
                    int n = 0;
    
                    for(Iterator var13 = currentWeights.iterator(); var13.hasNext(); ++n) {
                        Double d = (Double)var13.next();
                        if (d >= randomWeight) {
                            serverIndex = n;
                            break;
                        }
                    }
    
                    server = (Server)allList.get(serverIndex);
                } else {
                    server = super.choose(this.getLoadBalancer(), key);
                    if (server == null) {
                        return server;
                    }
                }
    
                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {
                        return server;
                    }
    
                    server = null;
                }
            }
    
            return server;
        }
    }

    debugµÄͼÀý£º

    ǰ¼¸´Î·ÃÎÊ£ºmaxTotalWeight¶¼ÊÇ0.0£¬Ê¹ÓÃÂÖѯ²ßÂÔ£¬µ«ÊÇ¿ªÊ¼»º´æÈ¨ÖØÊý¾Ý

    1616730100101_06.png

    30ÃëÖ®ºó£º¿ªÊ¼¸ù¾ÝÈ¨ÖØÊý¾ÝÀ´·ÖÅäÈ¨ÖØ£¬Ñ¡ÔñʵÀý

    1616730118844_07.png

    ÈçÏÂͼ£º8081¶Ë¿ÚµÄÈ¨ÖØÏÔȻûÓÐ8082µÄÈ¨ÖØ´ó£¬ËùÒÔ8082¶Ë¿ÚµÄuser·þÎñʵÀý±»·ÃÎʵĴÎÊý¶à

    1616730136639_08.png

    1616730143541_09.png

    3.4. RetryRule ÖØÊÔ²ßÂÔ

    ÖØÊÔ²ßÂÔÊÇָͨ¹ýÂÖѯ²ßÂÔÑ¡³öÒ»¸öʵÀý£¬È»ºóÈ¥·ÃÎÊ£¬Èç¹û´ËʵÀýΪnull»òÕßÒѾ­Ê§Ð§£¬ÄÇô»áÖØÊÔÆäËûµÄʵÀý£¬answer = this.subRule.choose(key); »á¸ù¾ÝÂÖѯ²ßÂÔÑ¡ÔñÒ»¸öʵÀý£¬È»ºóif ((answer == null || !answer.isAlive()) && System.currentTimeMillis() < deadline)ÅжÏÈç¹ûʵÀýΪnull»òÕßʧЧ£¬ÄÇô»áÖØÐÂÑ¡Ôñ

    public Server choose(ILoadBalancer lb, Object key) {
        long requestTime = System.currentTimeMillis();
        long deadline = requestTime + this.maxRetryMillis;
        Server answer = null;
        answer = this.subRule.choose(key);
        if ((answer == null || !answer.isAlive()) && System.currentTimeMillis() < deadline) {
            InterruptTask task = new InterruptTask(deadline - System.currentTimeMillis());
    
            while(!Thread.interrupted()) {
                answer = this.subRule.choose(key);
                if (answer != null && answer.isAlive() || System.currentTimeMillis() >= deadline) {
                    break;
                }
    
                Thread.yield();
            }
    
            task.cancel();
        }
    
        return answer != null && answer.isAlive() ? answer : null;
    }

    1616730163380_10.png

    3.5. BestAvailableRule ×îµÍ²¢·¢²ßÂÔ

    »á¸ù¾Ýÿ¸ö·þÎñʵÀýµÄ²¢·¢ÊýÁ¿À´¾ö¶¨£¬·ÃÎʲ¢·¢Êý×îÉÙµÄÄǸö·þÎñ£¬int concurrentConnections = serverStats.getActiveRequestsCount(currentTime); »á»ñµÃµ±Ç°±éÀúµÄʵÀýµÄ²¢·¢Êý£¬È»ºóºÍÆäËûµÄʵÀýµÄ²¢·¢Êý½øÐÐÅжÏ£¬×îÖÕ·ÃÎʲ¢·¢Á¿×îÉÙµÄÄǸöʵÀý

    public Server choose(Object key) {
        if (this.loadBalancerStats == null) {
            return super.choose(key);
        } else {
            List<Server> serverList = this.getLoadBalancer().getAllServers();
            int minimalConcurrentConnections = 2147483647;
            long currentTime = System.currentTimeMillis();
            Server chosen = null;
            Iterator var7 = serverList.iterator();
    
            while(var7.hasNext()) { //±éÀúËùÓеÄʵÀý
                Server server = (Server)var7.next();
                ServerStats serverStats = this.loadBalancerStats.getSingleServerStat(server);
                if (!serverStats.isCircuitBreakerTripped(currentTime)) {
                    int concurrentConnections = serverStats.getActiveRequestsCount(currentTime); //Åжϲ¢·¢Êý£¬²¢ºÍÒѾ­ÅжϳöµÄ×îÉٵIJ¢·¢Êý±È½Ï
                    if (concurrentConnections < minimalConcurrentConnections) {
                        minimalConcurrentConnections = concurrentConnections;
                        chosen = server;
                    }
                }
            }
    
            if (chosen == null) {
                return super.choose(key);
            } else {
                return chosen;
            }
        }
    }

    3.6. AvailabilityFilteringRule ¿ÉÓùýÂ˲ßÂÔ

    ´Ë²ßÂÔ»á´ÏÃ÷µÄ¹ýÂ˵ôһֱʧ°Ü²¢±»±ê¼ÇΪcircuit trippedµÄuser·þÎñ£¬¶øÇÒ»á¹ýÂ˵ôÄÇЩ¸ß²¢·¢µÄuser·þÎñ

    public Server choose(Object key) {
        int count = 0;
        
        for(Server server = this.roundRobinRule.choose(key); count++ <= 10; server = this.roundRobinRule.choose(key)) {
            //ͨ¹ýpredicateÀ´¹ýÂË
            if (this.predicate.apply(new PredicateKey(server))) {
                return server;
            }
        }
        //¹ýÂ˵ôһЩ·þÎñÖ®ºó£¬»á²ÉÓÃÂÖѯµÄ·½Ê½µ÷ÓÃʣϵķþÎñ
        return super.choose(key);
    }

    3.7. ClientConfigEnabledRoundRobinRule ×Ô¶¨Òå²ßÂÔ

    ´Ë²ßÂÔ±¾Éí²¢Ã»ÓÐʵÏÖÊ²Ã´ÌØÊâµÄ´¦ÀíÂß¼­£¬µ«ÊÇ¿ÉÒÔͨ¹ýÖØÖÃLoadBalancerÀ´´ïµ½×Ô¶¨ÒåһЩ¸ß¼¶²ßÂÔµÄÄ¿µÄ£¬¿ÉÒÔÖØÐ´initWithNiwsConfigºÍsetLoadBalancer

    public void initWithNiwsConfig(IClientConfig clientConfig) {
        this.roundRobinRule = new RoundRobinRule();
    }
    
    public void setLoadBalancer(ILoadBalancer lb) {
        super.setLoadBalancer(lb);
        this.roundRobinRule.setLoadBalancer(lb);
    }
    
    public Server choose(Object key) {
        if (this.roundRobinRule != null) {
            return this.roundRobinRule.choose(key);
        } else {
            throw new IllegalArgumentException("This class has not been initialized with the RoundRobinRule class");
        }
    }


    ²ÂÄãϲ»¶£º

    Ribbon¹¤×÷Ô­ÀíÏêϸ½éÉÜ

    ZookeeperÊÇÈçºÎѡȡÖ÷leaderµÄ£¿

    Spring CloudÊÇʲô£¿ÔõôÀí½âSpring Cloud?

    Spring BootÈçºÎʵÏÖ΢·þÎñ£¿/a>

    Spring¿ò¼Ü¹¦ÄÜ·ÖΪÄÄЩÄ£¿é£¿

    ÀÖÓãµç¾ºjavaÅàѵ¿Î³Ì

    0 ·ÖÏíµ½£º
    ºÍÎÒÃÇÔÚÏß½»Ì¸£¡
    ¡¾ÍøÕ¾µØÍ¼¡¿¡¾sitemap¡¿