您当前的位置:首页 > 电脑百科 > 程序开发 > 架构

Ribbon架构剖析

时间:2019-11-12 14:53:54  来源:  作者:
Ribbon架构剖析

 

在学习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();
}

这个接口中保护了一个基本的负载均衡器所必须的所有功能:

  1. addServers(List)向负载均衡器中添加服务实例
  2. chooseServer(Object)根据负载均衡策略,从负载均衡器中挑选出一个服务实例
  3. markServerDown(Server)下线负载均衡器中的某个具体实例
  4. getReachableServers()返回当前可正常服务的实例列表
  5. getAllServers()返回所有的服务实例列表

接着来看一下这个接口的UML图

Ribbon架构剖析

 

首先看AbstractLoadBalancer这个类,这个类是ILoadBalancer接口的抽象类实现。在这个抽象类中定义了一个表示服务实例状态的枚举的同时还新增了两个抽象方法:

 public enum ServerGroup{
 ALL,
 STATUS_UP,
 STATUS_NOT_UP
 }
 public abstract List<Server> getServerList(ServerGroup serverGroup);
 public abstract LoadBalancerStats getLoadBalancerStats();
  1. getServerList(ServerGroup):根据分组类型来返回不同的服务实例列表。
  2. getLoadBalancerStats():返回LoadBalancerStatus对象,这个LoadBalancerStats对象是用来存储负载均衡器中各个服务实例当前的属性和统计信息的

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的实现类有以下几种:

  1. PingUrl:使用HttpClient去get请求某个url,判断其是否alive
  2. PingConstant:固定返回某服务是否可用,默认返回true
  3. NoOpPing:没有任何操作,直接返回true
  4. DummyPing:同样是直接返回true
  5. NIWSDiscoveryPing:根据服务的实例对象InstanceInfo的InstanceStatus去判断,如果为InstanceStatus.UP,则为可用

心跳检测策略对象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线性轮询

除此之外的实现为:

  1. BestAvailableRule:选择最小请求数
  2. RandomRule:随机选择
  3. RetryRule:轮询重试
  4. WeightedResponseTimeRule:根据响应时间分配权重
  5. ZoneAvoidanceRule:根据服务的分区可用性轮询

现在继续看BaseLoadBalancer的子类DynamicServerListLoadBalancer

这个类对基础负载均衡器做了扩展。扩展的功能如下:

  1. 服务实例运行期间的动态更新
  2. 服务实例的过滤

服务列表

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();
}

它的实现类有两个:

  1. PollingServerListUpdater:通过定时任务进行更新
  2. EurekaNotificationServerListUpdater:利用Eureka的事件监听器来更新

服务列表过滤器

public interface ServerListFilter<T extends Server> {

 public List<T> getFilteredListOfServers(List<T> servers);

}

该接口主要用于根据一些规则过滤传入的服务实例列表,该接口的实现类如下:

  1. ZoneAffinityServerListFilter:基于Eureka的分区规则对服务实例的过滤
  2. DefaultNIWSServerListFilter:ZoneAffinityServerListFilter的子类且没有做特殊的更新
  3. ServerListSubsetFilter:通过比较服务实例的通信失败数和并发连接数来剔除那些相对不够健康的实例
  4. ZonePreferenceServerListFilter:使用SpringCloud整合eureka和ribbon时默认使用的该过滤器。它实现了通过配置或eureka实例无数据的所属区域(Zone)来过滤出同区域的服务实例

ZoneAwareLoadBalancer则是对DynamicServerListLoadBalancer的扩展,它主要增加了区域过滤的功能

关注公众号:http://mp.weixin.qq.com/mp/homepage?__biz=MzU5MDgzOTYzMw==&hid=3&sn=ee8e8ecbdc8d22253994debf927273f5&scene=18#wechat_redirect,查看更多Spring、SpringBoot、SpringCloud源码解析系列文章



Tags:Ribbon架构   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
在学习Ribbon之前,先看一下这张图,这张图完美的把Ribbon的基础架构给描述出来了这张图的核心是负载均衡管理器,围绕着它的是外面的这5大功能点,咱们就从核心开始看然后再带出来...【详细内容】
2019-11-12  Tags: Ribbon架构  点击:(118)  评论:(0)  加入收藏
▌简易百科推荐
为了构建高并发、高可用的系统架构,压测、容量预估必不可少,在发现系统瓶颈后,需要有针对性地扩容、优化。结合楼主的经验和知识,本文做一个简单的总结,欢迎探讨。1、QPS保障目标...【详细内容】
2021-12-27  大数据架构师    Tags:架构   点击:(5)  评论:(0)  加入收藏
前言 单片机开发中,我们往往首先接触裸机系统,然后到RTOS,那么它们的软件架构是什么?这是我们开发人员必须认真考虑的问题。在实际项目中,首先选择软件架构是非常重要的,接下来我...【详细内容】
2021-12-23  正点原子原子哥    Tags:架构   点击:(7)  评论:(0)  加入收藏
现有数据架构难以支撑现代化应用的实现。 随着云计算产业的快速崛起,带动着各行各业开始自己的基于云的业务创新和信息架构现代化,云计算的可靠性、灵活性、按需计费的高性价...【详细内容】
2021-12-22    CSDN  Tags:数据架构   点击:(10)  评论:(0)  加入收藏
▶ 企业级项目结构封装释义 如果你刚毕业,作为Java新手程序员进入一家企业,拿到代码之后,你有什么感觉呢?如果你没有听过多模块、分布式这类的概念,那么多半会傻眼。为什么一个项...【详细内容】
2021-12-20  蜗牛学苑    Tags:微服务   点击:(9)  评论:(0)  加入收藏
我是一名程序员关注我们吧,我们会多多分享技术和资源。进来的朋友,可以多了解下青锋的产品,已开源多个产品的架构版本。Thymeleaf版(开源)1、采用技术: springboot、layui、Thymel...【详细内容】
2021-12-14  青锋爱编程    Tags:后台架构   点击:(21)  评论:(0)  加入收藏
在了解连接池之前,我们需要对长、短链接建立初步认识。我们都知道,网络通信大部分都是基于TCP/IP协议,数据传输之前,双方通过“三次握手”建立连接,当数据传输完成之后,又通过“四次挥手”释放连接,以下是“三次握手”与“四...【详细内容】
2021-12-14  架构即人生    Tags:连接池   点击:(17)  评论:(0)  加入收藏
随着移动互联网技术的快速发展,在新业务、新领域、新场景的驱动下,基于传统大型机的服务部署方式,不仅难以适应快速增长的业务需求,而且持续耗费高昂的成本,从而使得各大生产厂商...【详细内容】
2021-12-08  架构驿站    Tags:分布式系统   点击:(23)  评论:(0)  加入收藏
本系列为 Netty 学习笔记,本篇介绍总结Java NIO 网络编程。Netty 作为一个异步的、事件驱动的网络应用程序框架,也是基于NIO的客户、服务器端的编程框架。其对 Java NIO 底层...【详细内容】
2021-12-07  大数据架构师    Tags:Netty   点击:(17)  评论:(0)  加入收藏
前面谈过很多关于数字化转型,云原生,微服务方面的文章。虽然自己一直做大集团的SOA集成平台咨询规划和建设项目,但是当前传统企业数字化转型,国产化和自主可控,云原生,微服务是不...【详细内容】
2021-12-06  人月聊IT    Tags:架构   点击:(23)  评论:(0)  加入收藏
微服务看似是完美的解决方案。从理论上来说,微服务提高了开发速度,而且还可以单独扩展应用的某个部分。但实际上,微服务带有一定的隐形成本。我认为,没有亲自动手构建微服务的经历,就无法真正了解其复杂性。...【详细内容】
2021-11-26  GreekDataGuy  CSDN  Tags:单体应用   点击:(35)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条