负载均衡器之AbstractLoadBalancer

486 阅读2分钟

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

9负载均衡器之AbstractLoadBalancer

AbstractLoadBalancer

AbstractLoadBalancer是ILoadBalancer接口的抽象实现

public abstract class AbstractLoadBalancer implements ILoadBalancer {
    
    public enum ServerGroup{
        ALL,
        STATUS_UP,
        STATUS_NOT_UP        
    }
        
    /**
     * delegate to {@link #chooseServer(Object)} with parameter null.
     */
    public Server chooseServer() {
       return chooseServer(null);
    }

    
    /**
     * List of servers that this Loadbalancer knows about
     * 
     * @param serverGroup Servers grouped by status, e.g., {@link ServerGroup#STATUS_UP}
     */
    public abstract List<Server> getServerList(ServerGroup serverGroup);
    
    /**
     * Obtain LoadBalancer related Statistics
     */
    public abstract LoadBalancerStats getLoadBalancerStats();    
}

定义枚举类ServerGroup

  • ALL 所有服务实例
  • STATUS_UP:正常服务实例
  • STATUS_NOT_UP:停止服务实例

抽象方法

getServerList(ServerGroup serverGroup):定义了根据分组类型来获取不同服务实例的列表

getLoadBalancerStats(); 定义获取LoadBalancerStats对象的方法,LoadBalancerStats对象被用来存储负载均衡器中各个服务实例当前的属性和统计信息。

BaseLoadBalancer

BaseLoadBalancer是Ribbon负载均衡器的基础实现类

  • 定义并维护两个存储服务实例Server对象的列表,一个用于存储所有服务实例的清单,一个用于存储正常服务的实例清单

    @Monitor(name = PREFIX + "AllServerList", type = DataSourceType.INFORMATIONAL)
    protected volatile List<Server> allServerList = Collections
            .synchronizedList(new ArrayList<Server>());
    @Monitor(name = PREFIX + "UpServerList", type = DataSourceType.INFORMATIONAL)
    protected volatile List<Server> upServerList = Collections
            .synchronizedList(new ArrayList<Server>());
    
  • 定义之前用来存储负载均衡器各服务实例属性和统计信息的LoadBalancerStats对象。

  • 定义了检查服务实例是否正常服务的IPing对象,在BaseLoadBalancer中默认为null,需要在构造时注入它的具体实现

  • 定义了检查服务实例操作的执行策略对象IPingStrategy,默认使用了该类中定义的静态内部类

 private static class SerialPingStrategy implements IPingStrategy {
 
     @Override
     public boolean[] pingServers(IPing ping, Server[] servers) {
         int numCandidates = servers.length;
         boolean[] results = new boolean[numCandidates];
 
         if (logger.isDebugEnabled()) {
             logger.debug("LoadBalancer:  PingTask executing ["
                          + numCandidates + "] servers configured");
         }
 
         for (int i = 0; i < numCandidates; i++) {
             results[i] = false; /* Default answer is DEAD. */
             try {
                 // NOTE: IFF we were doing a real ping
                 // assuming we had a large set of servers (say 15)
                 // the logic below will run them serially
                 // hence taking 15 times the amount of time it takes
                 // to ping each server
                 // A better method would be to put this in an executor
                 // pool
                 // But, at the time of this writing, we dont REALLY
                 // use a Real Ping (its mostly in memory eureka call)
                 // hence we can afford to simplify this design and run
                 // this
                 // serially
                 if (ping != null) {
                     results[i] = ping.isAlive(servers[i]);
                 }
             } catch (Throwable t) {
                 logger.error("Exception while pinging Server:"
                              + servers[i], t);
             }
         }
         return results;
     }
 }
  • 定义负载均衡的处理规则IRule对象,负载均衡器实际将服务实例选择任务委托给IRule实例的choose方法来实现,默认初始化RoundRobinRule为IRule实现对象,RoundRobinRule实现了基本的线性负载均衡规则。
public Server chooseServer(Object key) {
    if (counter == null) {
        counter = createCounter();
    }
    counter.increment();
    if (rule == null) {
        return null;
    } else {
        try {
            return rule.choose(key);
        } catch (Throwable t) {
            return null;
        }
    }
}

启动ping任务:BaseLoadBalancer默认构造方法中,直接启动一个用于定时检查Server是否健康的任务。任务默认执行间隔为10s

实现ILoadBalancer接口:

chooseServer方法

addServers方法:

public void addServers(List<Server> newServers) {
    if (newServers != null && newServers.size() > 0) {
        try {
            ArrayList<Server> newList = new ArrayList<Server>();
            newList.addAll(allServerList);
            newList.addAll(newServers);
            setServersList(newList);
        } catch (Exception e) {
            logger.error("Exception while adding Servers", e);
        }
    }
}

getReachableServers方法:获取可用的服务实例列表

public List<Server> getReachableServers() {
    return Collections.unmodifiableList(upServerList);
}

单独维护一个正常服务的实例清单,直接返回即可

getAllServers方法:获取所有服务实例列表

@Override
public List<Server> getAllServers() {
    return Collections.unmodifiableList(allServerList);
}