public interface IRule{ public Server choose(Object key); public void setLoadBalancer(ILoadBalancer lb); public ILoadBalancer getLoadBalancer(); } IRule接口的实现类有以下几种:
if (server.isAlive() && (server.isReadyToServe())) { return (server); }
// Next. server = null; }
if (count >= 10) { log.warn("No available alive servers after 10 tries from load balancer: " + lb); } return server; }
/** * Inspired by the implementation of {@link AtomicInteger#incrementAndGet()}. * * @param modulo The modulo to bound the value of the counter. * @return The next value. */ private int incrementAndGetModulo(int modulo) { for (;;) { int current = nextServerCyclicCounter.get(); int next = (current + 1) % modulo; if (nextServerCyclicCounter.compareAndSet(current, next)) return next; } } WeightedResponseTimeRule继承了RoundRobinRule,开始的时候还没有权重列表,采用父类的轮询方式,有一个默认每30秒更新一次权重列表的定时任务,该定时任务会根据实例的响应时间来更新权重列表,choose方法做的事情就是,用一个(0,1)的随机double数乘以最大的权重得到randomWeight,然后遍历权重列表,找出第一个比randomWeight大的实例下标,然后返回该实例,代码略。
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) { // 比较各个服务器之间的请求数,然后选取请求数最少的服务器并放到chosen变量中 minimalConcurrentConnections = concurrentConnections; chosen = server; } } } if (chosen == null) { // 如果没有选上,调用父类ClientConfigEnabledRoundRobinRule的choose方法,也就是使用RoundRobinRule轮询的方式进行负载均衡 return super.choose(key); } else { return chosen; } } 使用Ribbon提供的负载均衡策略很简单,只需以下几部: