小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
20负载均衡策略AvailabilityFilteringRule
AvailabilityFilteringRule
/*
*
* Copyright 2013 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.netflix.loadbalancer;
import java.util.List;
import com.google.common.collect.Collections2;
import com.netflix.client.config.IClientConfig;
import com.netflix.servo.annotations.DataSourceType;
import com.netflix.servo.annotations.Monitor;
/**
* A load balancer rule that filters out servers that:
* <ul>
* <li> are in circuit breaker tripped state due to consecutive connection or read failures, or</li>
* <li> have active connections that exceeds a configurable limit (default is Integer.MAX_VALUE).</li>
* </ul>
* The property
* to change this limit is
* <pre>{@code
*
* <clientName>.<nameSpace>.ActiveConnectionsLimit
*
* }</pre>
*
* <p>
*
* @author awang
*
*/
public class AvailabilityFilteringRule extends PredicateBasedRule {
private AbstractServerPredicate predicate;
public AvailabilityFilteringRule() {
super();
predicate = CompositePredicate.withPredicate(new AvailabilityPredicate(this, null))
.addFallbackPredicate(AbstractServerPredicate.alwaysTrue())
.build();
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
predicate = CompositePredicate.withPredicate(new AvailabilityPredicate(this, clientConfig))
.addFallbackPredicate(AbstractServerPredicate.alwaysTrue())
.build();
}
@Monitor(name="AvailableServersCount", type = DataSourceType.GAUGE)
public int getAvailableServersCount() {
ILoadBalancer lb = getLoadBalancer();
List<Server> servers = lb.getAllServers();
if (servers == null) {
return 0;
}
return Collections2.filter(servers, predicate.getServerOnlyPredicate()).size();
}
/**
* This method is overridden to provide a more efficient implementation which does not iterate through
* all servers. This is under the assumption that in most cases, there are more available instances
* than not.
*/
@Override
public Server choose(Object key) {
int count = 0;
Server server = roundRobinRule.choose(key);
while (count++ <= 10) {
if (predicate.apply(new PredicateKey(server))) {
return server;
}
server = roundRobinRule.choose(key);
}
return super.choose(key);
}
@Override
public AbstractServerPredicate getPredicate() {
return predicate;
}
}
AvailabilityFilteringRule继承了PredicateBasedRule,采用先过滤清单后轮询选择的基本处理逻辑,过滤条件使用了AvailabilityPredicate的apply方法:
@Override
public boolean apply(@Nullable PredicateKey input) {
LoadBalancerStats stats = getLBStats();
if (stats == null) {
return true;
}
return !shouldSkipServer(stats.getSingleServerStat(input.getServer()));
}
AvailabilityFilteringRule重写了choose方法,没有像PredicateBasedRule中的先遍历所有的节点进行过滤,然后从过滤后的集合中选择实例,而是先线性选择一个实例,然后用过滤条件判断是否满足条件,如此循环,重复10次没有找到再采用父类的实现方案。