一、负载均衡类图
二、AbstractLoadBalancerRule源码
//负载均衡策略的抽象类
public abstract class AbstractLoadBalancerRule implements IRule, IClientConfigAware {
//该对象能够在具体实现选择服务策略时,获取一些负载均衡器中维护的信息来作为分配依据
private ILoadBalancer lb;
@Override
public void setLoadBalancer(ILoadBalancer lb){
this.lb = lb;
}
@Override
public ILoadBalancer getLoadBalancer(){
return lb;
}
}
三、RandomRule源码
public class RandomRule extends AbstractLoadBalancerRule {
//从服务清单中随机选择一个服务实例
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
//负载均衡来获得可用实例列表upList和allList
List<Server> upList = lb.getReachableServers();
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
//随机来获取一个随机数
int index = chooseRandomInt(serverCount);
//随机数作为upList的索引值来返回具体实例
server = upList.get(index);
if (server == null) {
/*
* The only time this should happen is if the server list were
* somehow trimmed. This is a transient condition. Retry after
* yielding.
*/
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
// Shouldn't actually happen.. but must be transient or a bug.
server = null;
Thread.yield();
}
//正常情况下,每次都应该可以选择一个服务实例
return server;
}
protected int chooseRandomInt(int serverCount) {
return ThreadLocalRandom.current().nextInt(serverCount);
}
//接口中的choose委托给该类中的choose(getLoadBalancer(), key)方法
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
// TODO Auto-generated method stub
}
}
注意:serverCount取allList.size(),取得随机数以后再从upList中取服务实例可能出现下标越界异常,因为allList.size >= upList.size()。