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; }
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位置。
今天先到这里,接下来继续学习
阅读全文
0 0
- springCloud(九)
- SpringCloud教程九:服务链路追踪(SpringCloud Sleuth)
- 【SpringCloud】(九):Feign的自定义配置
- SpringCloud
- springcloud
- SpringCloud
- springcloud
- springcloud
- springcloud
- SpringCloud(九):Ribbon脱离Eureka使用及原生api
- springcloud(九):配置中心和消息总线(配置中心终结版)
- springcloud(九):配置中心和消息总线(配置中心终结版)
- idea创建springcloud项目图文教程(Feign实现负载均衡)(九)
- springcloud(九):配置中心和消息总线(配置中心终结版)
- springcloud(九):配置中心和消息总线(配置中心终结版) 2017/05/26
- SpringCloud(六)springcloud feign
- 【springCloud】springCloud中文手册
- 【SpringCloud】SpringCloud简介
- 分享初学Electron遇到的坑和避免被坑
- 有关servlet,servletContext和response
- 单例模式五种方法
- String、stringbuffer、Stringbuilder的区别和讲解
- el&jstl
- springCloud(九)
- 输出菱形
- loadrunner Web_类函数之web_switch_net_layer()
- AI challenger 场景分类 PyTorch 迁移学习 resnet18
- Eclipse接入第三方动态库.so方案
- hbase表数据的写入流程:(根据rowkey进行写入)
- [LeetCode]322. Coin Change
- 如何理解左操作数必须为左值
- 9月23日java总结