springCloud(九)

来源:互联网 发布:gta男性捏脸数据 编辑:程序博客网 时间:2024/04/30 10:00

上一篇学习到了LoadBalance的其中一个关键组成部分是负载均衡策略,其最基础的接口是IRule。

public interface IRule{    /*     * choose one alive server from lb.allServers or     * lb.upServers according to key     *      * @return choosen Server object. NULL is returned if none     *  server is available      */    public Server choose(Object key);        public void setLoadBalancer(ILoadBalancer lb);        public ILoadBalancer getLoadBalancer();    }

我们可以看到Ribbon已经实现接口的:



我们挨个看一遍,

首先是AvailabilityFilteringRule,他会根据把特殊情况的server排除,

特殊情况包括  1:in circuit breaker tripped state due to consecutive connection or read failures

2: have active connections that exceeds a configurable limit 

        一个是处于短路状态,一个是超过了最大连接数。

     过滤逻辑在AvailabilityPredicate中,

 @Override    public boolean apply(@Nullable PredicateKey input) {        LoadBalancerStats stats = getLBStats();        if (stats == null) {            return true;        }        return !shouldSkipServer(stats.getSingleServerStat(input.getServer()));    }            private boolean shouldSkipServer(ServerStats stats) {                if ((CIRCUIT_BREAKER_FILTERING.get() && stats.isCircuitBreakerTripped())                 || stats.getActiveRequestsCount() >= activeConnectionsLimit.get()) {            return true;        }        return false;    }



接下来是BestAvailableRule,首先是过滤掉短路状态的服务,在可用服务中选择并发数最小的。

 public Server choose(Object key) {        if (loadBalancerStats == null) {            return super.choose(key);        }        List<Server> serverList = getLoadBalancer().getAllServers();        int minimalConcurrentConnections = Integer.MAX_VALUE;        long currentTime = System.currentTimeMillis();        Server chosen = null;        for (Server server: serverList) {            ServerStats serverStats = loadBalancerStats.getSingleServerStat(server);            if (!serverStats.isCircuitBreakerTripped(currentTime)) {                int concurrentConnections = serverStats.getActiveRequestsCount(currentTime);                if (concurrentConnections < minimalConcurrentConnections) {                    minimalConcurrentConnections = concurrentConnections;                    chosen = server;                }            }        }        if (chosen == null) {            return super.choose(key);        } else {            return chosen;        }    }

我们可以看到,比较简单,遍历一遍所有的server,去除掉短路状态的服务后,选择出并发量最小的。


接下来是RandomRule,随机选择一个服务。

接下来是RetryRule,在已经有的规则上增加重试机制,默认情况下重试机制的规则是RoundRobinRule。

接下来是RoundRobinRule,轮训的方式选择server,其主要是保存了一个 AtomicInteger nextServerCyclicCounter;利用CAS保证线程安全。

其计算index的算法如下:

private int incrementAndGetModulo(int modulo) {        for (;;) {            int current = nextServerCyclicCounter.get();            int next = (current + 1) % modulo;            if (nextServerCyclicCounter.compareAndSet(current, next))                return next;        }    }
其中modulo就是服务的总数量。

最后一个是WeightedResponseTimeRule,动态的利用response时间计算全职。

doc中的例子非常好:

* The basic idea for weighted round robin has been obtained from JCS * The implementation for choosing the endpoint from the list of endpoints * is as follows:Let's assume 4 endpoints:A(wt=10), B(wt=30), C(wt=40),  * D(wt=20).  * <p> * Using the Random API, generate a random number between 1 and10+30+40+20. * Let's assume that the above list is randomized. Based on the weights, we * have intervals as follows: * <p> * 1-----10 (A's weight) * <br> * 11----40 (A's weight + B's weight) * <br> * 41----80 (A's weight + B's weight + C's weight) * <br> * 81----100(A's weight + B's weight + C's weight + C's weight) * <p> * Here's the psuedo code for deciding where to send the request: * <p> * if (random_number between 1 & 10) {send request to A;} * <br> * else if (random_number between 11 & 40) {send request to B;} * <br> * else if (random_number between 41 & 80) {send request to C;} * <br> * else if (random_number between 81 & 100) {send request to D;} * <p> * When there is not enough statistics gathered for the servers, this rule * will fall back to use {@link RoundRobinRule}.

其实就是把总体看做一个圆盘,权重越大所占的面积越大,随机数落在其区域的概率越大。当统计稿率不足时,使用RoundRobinRule。

 // holds the accumulated weight from index 0 to current index    // for example, element at index 2 holds the sum of weight of servers from 0 to 2    private volatile List<Double> accumulatedWeights = new ArrayList<Double>();

其中把累加概率保存到了一个列表里,每次计算一个随机数,第一个大于随机数的位置,就是待选泽的server位置。


今天先到这里,接下来继续学习





原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 c盘和d盘换换了怎么办 晚上2点到3点醒怎么办 红米3s变砖了怎么办 6s锁屏密码忘了怎么办 怀孕9个月了胃疼怎么办 怀孕6个月了胃疼怎么办 孕妇胃疼怎么办4个月了 25岁欠了5万块钱怎么办 感冒嗓子疼怎么办最简单的方法 和老婆离婚了我的心好痛怎么办 4s店不给退定金怎么办 教你闪腰了后该怎么办 coolpad酷派手机开不了机怎么办 苹果5s黑屏开不了机怎么办 苹果4s的屏坏了怎么办 苹果6手机充电口接触不良怎么办 5s用久了卡顿怎么办 孕妇血糖高怎么办什么方法降最好 脚砸了肿了紫了怎么办 我想在淘宝上卖东西该怎么办 苹果手机4s开不了机怎么办 冒险岛s前出2条怎么办 狗狗又吐又拉血怎么办 小孩上网成瘾怎么办父母要怎么做 一只眼睛大一只眼睛小怎么办 带近视镜时间长了眼睛变形怎么办 联通卡2g换4g卡怎么办 上火牙疼怎么办教你立刻止疼 吃热的凉的牙疼怎么办 我买的股票退市了怎么办 如果起诉离婚另一方不出庭怎么办 10个月宝宝还没长牙怎么办 超敏c反应蛋白>5怎么办 怀孕才两个月肚子就大了怎么办 腰椎间盘突出腿疼厉害怎么办 打了促排卵针不排卵怎么办 孕34周隐血1十是怎么办 窦性心动过缓伴不齐怎么办 09年买的万科b怎么办 苹果5s手机打不开机怎么办 剖腹产后一年半后意外怀孕怎么办