在学习Ribbon之前,先看一下这张图,这张图完美的把Ribbon的基础架构给描述出来了
这张图的核心是负载均衡管理器,围绕着它的是外面的这5大功能点,咱们就从核心开始看然后再带出来其他的功能
首先看一下负载均衡器的核心接口ILoadBalancer
public interface ILoadBalancer { public void addServers(List<Server> newServers); public Server chooseServer(Object key); public void markServerDown(Server server); public List<Server> getReachableServers(); public List<Server> getAllServers(); }
这个接口中保护了一个基本的负载均衡器所必须的所有功能:
接着来看一下这个接口的UML图
首先看AbstractLoadBalancer这个类,这个类是ILoadBalancer接口的抽象类实现。在这个抽象类中定义了一个表示服务实例状态的枚举的同时还新增了两个抽象方法:
public enum ServerGroup{ ALL, STATUS_UP, STATUS_NOT_UP } public abstract List<Server> getServerList(ServerGroup serverGroup); public abstract LoadBalancerStats getLoadBalancerStats();
AbstractLoadBalancer共有两个实现类,右侧的NoOpLoadBalancer是一个空的实现类,这里可以忽略不计。这里接着继续看BaseLoadBalancer
BaseLoadBalancer是负载均衡器的基础实现类,这个类对于接口ILoadBalancer的所有方法都给予了基础的实现,除此之外还保护了很多重要的对象
两个存储当前服务实例对象的列表,一个是包含所有服务、一个是包含正常服务
@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>());
存储负载系统器各服务实例属性和统计信息的对象
protected LoadBalancerStats lbStats;
心跳检测对象
protected IPing ping = null;
IPing是用来向服务发起心跳检测的,通过心跳检测来判断该服务是否可用。IPing的实现类有以下几种:
心跳检测策略对象IPingStrategy
private final static SerialPingStrategy DEFAULT_PING_STRATEGY = new SerialPingStrategy(); protected IPingStrategy pingStrategy = DEFAULT_PING_STRATEGY;
默认实现是线型轮询
负载均衡策略对象
private final static IRule DEFAULT_RULE = new RoundRobinRule(); protected IRule rule = DEFAULT_RULE;
IRule是在选择实例的时候的负载均衡策略对象,默认使用的是RoundRobinRule线性轮询
除此之外的实现为:
现在继续看BaseLoadBalancer的子类DynamicServerListLoadBalancer
这个类对基础负载均衡器做了扩展。扩展的功能如下:
服务列表
public interface ServerList<T extends Server> { /** * 获取初始化的服务列表 */ public List<T> getInitialListOfServers(); /** * 获取更新后的服务列表 */ public List<T> getUpdatedListOfServers(); }
在DynamicServerListLoadBalancer中默认使用的服务列表实现类是DomainExtractingServerList,只不过该服务列表内部还定义了一个服务列表,这个服务列表的实现类则是DiscoveryEnabledNIWSServerList
这个最终的服务列表的数据来源则主要依靠EurekaClient从注册中心获取
服务列表更新
这个接口定义了一系列的对服务列表的更新操作
public interface ServerListUpdater { //内部接口 public interface UpdateAction { //实现对服务列表的更新操作 void doUpdate(); } //启动服务更新器 void start(UpdateAction updateAction); //停止服务更新器 void stop(); //返回最近的更新时间戳 String getLastUpdate(); //返回上一次更新到现在的时间间隔(ms) long getDurationSinceLastUpdateMs(); //返回错过的更新周期数 int getNumberMissedCycles(); //返回核心线程数 int getCoreThreads(); }
它的实现类有两个:
服务列表过滤器
public interface ServerListFilter<T extends Server> { public List<T> getFilteredListOfServers(List<T> servers); }
该接口主要用于根据一些规则过滤传入的服务实例列表,该接口的实现类如下:
ZoneAwareLoadBalancer则是对DynamicServerListLoadBalancer的扩展,它主要增加了区域过滤的功能
关注公众号:http://mp.weixin.qq.com/mp/homepage?__biz=MzU5MDgzOTYzMw==&hid=3&sn=ee8e8ecbdc8d22253994debf927273f5&scene=18#wechat_redirect,查看更多Spring、SpringBoot、SpringCloud源码解析系列文章