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();
}
这个接口中保护了一个基本的负载均衡器所必须的所有功能:
addServers(List)
向负载均衡器中添加服务实例chooseServer(Object)
根据负载均衡策略,从负载均衡器中挑选出一个服务实例markServerDown(Server)
下线负载均衡器中的某个具体实例getReachableServers()
返回当前可正常服务的实例列表getAllServers()
返回所有的服务实例列表
接着来看一下这个接口的UML图
首先看AbstractLoadBalancer
这个类,这个类是ILoadBalancer
接口的抽象类实现。
在这个抽象类中定义了一个表示服务实例状态的枚举的同时还新增了两个抽象方法:
public enum ServerGroup{
ALL,
STATUS_UP,
STATUS_NOT_UP
}
public abstract List<Server> getServerList(ServerGroup serverGroup);
public abstract LoadBalancerStats getLoadBalancerStats();
getServerList(ServerGroup)
:根据分组类型来返回不同的服务实例列表。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
的实现类有以下几种:
PingUrl
:使用HttpClient去get请求某个url,判断其是否alivePingConstant
:固定返回某服务是否可用,默认返回trueNoOpPing
:没有任何操作,直接返回trueDummyPing
:同样是直接返回trueNIWSDiscoveryPing
:根据服务的实例对象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
线性轮询
除此之外的实现为:
BestAvailableRule
:选择最小请求数RandomRule
:随机选择RetryRule
:轮询重试WeightedResponseTimeRule
:根据响应时间分配权重ZoneAvoidanceRule
:根据服务的分区可用性轮询
现在继续看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();
}
它的实现类有两个:
PollingServerListUpdater
:通过定时任务进行更新EurekaNotificationServerListUpdater
:利用Eureka的事件监听器来更新
服务列表过滤器
public interface ServerListFilter<T extends Server> {
public List<T> getFilteredListOfServers(List<T> servers);
}
该接口主要用于根据一些规则过滤传入的服务实例列表,该接口的实现类如下:
ZoneAffinityServerListFilter
:基于Eureka的分区规则对服务实例的过滤DefaultNIWSServerListFilter
:ZoneAffinityServerListFilter
的子类且没有做特殊的更新ServerListSubsetFilter
:通过比较服务实例的通信失败数和并发连接数来剔除那些相对不够健康的实例ZonePreferenceServerListFilter
:使用SpringCloud整合eureka和ribbon时默认使用的该过滤器。它实现了通过配置或eureka实例无数据的所属区域(Zone)来过滤出同区域的服务实例
ZoneAwareLoadBalancer
则是对DynamicServerListLoadBalancer
的扩展,它主要增加了区域过滤的功能
Ribbon架构剖析的更多相关文章
- SQLServer内核架构剖析 (转载)
SQL Server内核架构剖析 (转载) 这篇文章在我电脑里好长时间了,今天不小心给翻出来了,觉得写得很不错,因此贴出来共享. 不得不承认的是,一个优秀的软件是一步一步脚踏实地积累起来的,众多优秀的 ...
- [转]分布式文件系统FastDFS架构剖析
[转]分布式文件系统FastDFS架构剖析 http://www.programmer.com.cn/4380/ 文/余庆 FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实 ...
- 《Netty5.0架构剖析和源码解读》【PDF】下载
<Netty5.0架构剖析和源码解读>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062545 内容简介 Netty 是个异步的 ...
- Nebula 架构剖析系列(一)图数据库的存储设计
摘要 在讨论某个数据库时,存储 ( Storage ) 和计算 ( Query Engine ) 通常是讨论的热点,也是爱好者们了解某个数据库不可或缺的部分.每个数据库都有其独有的存储.计算方式,今天 ...
- Nebula 架构剖析系列(二)图数据库的查询引擎设计
摘要 上文(存储篇)说到数据库重要的两部分为存储和计算,本篇内容为你解读图数据库 Nebula 在查询引擎 Query Engine 方面的设计实践. 在 Nebula 中,Query Engine ...
- [转载]SQL Server内核架构剖析
原文链接:http://www.sqlserver.com.cn 我们做管理软件的,主要核心就在数据存储管理上.所以数据库设计是我们的重中之重.为了让我们的管理软件能够稳定.可扩展.性能优秀.可跟踪排 ...
- SQLSERVER内核架构剖析 (转)
我们做管理软件的,主要核心就在数据存储管理上.所以数据库设计是我们的重中之重.为了让我们的管理软件能够稳定.可扩展.性能优秀.可跟踪排错. 可升级部署.可插件运行,我们往往研发自己的管理软件开发平台. ...
- Spring-Cloud之Ribbon原理剖析
我们知道Ribbon主要的工作就是进行负载均衡,帮助我们无需再关注微服务中集群的地址信息,因此在源码剖析中我们就主要关注这部分的内容. 内置的负载均衡规则 RoundRobinRule:直接轮询的方案 ...
- Ranger架构剖析
Ranger介绍 2016年,Hadoop迎来了自己十周岁生日.过去的十年,Hadoop雄霸武林盟主之位,号令天下,引领大数据技术生态不断发展壮大,一时间百家争鸣,百花齐放.然而,兄弟多了不好管,为了 ...
随机推荐
- CSTC-2017-Web-writeup
0x01 前言 这一次的比赛web题只做出来3个,也是菜的抠脚.. 0x02 web-签到题 php弱类型 查看源码,发现是代码审计,要求用户名必须为字母,密码必须为数字,登陆页面可以用开头为0 ...
- 搭建RTMP直播流服务器
最近项目比较紧张,所以没什么时间写博客,正好这几天没什么事,赶紧记录下自己最近所学. 环境配置 服务器选用 服务器我选择的是小鸟云 ,原因很简单,他的个人用户有3个月免费使用时间. 服务器环境 Win ...
- 使用 Vim 搭建 C/C++ 开发环境
原文链接: https://spacevim.org/cn/use-vim-as-a-c-cpp-ide/ SpaceVim 是一个模块化的 Vim IDE,针对 C/C++ 语言的支持主要依靠 la ...
- PyCharm重命名文件时更改引用的地方
Shift + F6 在文件夹直接更改文件名称时,其它文件里有调用这个模块的话,名称是不会改变的,只会报错,显示找不到这个模块,这时,可以在pycharm里直接更改 右键你需要改名的文件,选择Refa ...
- df 查看磁盘使用情况
1.查看磁盘使用情况 2.查看boot目录详情 3.提取已使用的百分比 4.切割提取出数字
- [C3W1] Structuring Machine Learning Projects - ML Strategy 1
第一周:机器学习策略(1)(ML Strategy(1)) 为什么是ML策略?(Why ML Strategy) 大家好,欢迎收听本课,如何构建你的机器学习项目也就是说机器学习的策略.我希望通过这门课 ...
- 1.web2
听说聪明的人都能找到答案http://123.206.87.240:8002/web2/ 直接查看源码~~~
- MongoDB概念认识(四)
1. database 一个mongodb中可以建立多个数据库. MongoDB的默认数据库为"db",该数据库存储在data目录中. MongoDB的单个实例可以容纳多个独立的数 ...
- pandas-缺失值处理
import pandas as pd import numpy as np Step 1.加载数据集 # header=0以第一行作为列名 tip = pd.read_csv("lianx ...
- 日常笔记6C++标准模板库(STL)用法介绍实例
一.vector常见用法详解 vector翻译为向量,但是这里翻译成变长数组的叫法更好理解. 如果typename是一个STL容器,定义的时候要记得在>>符号之间加上空格,因为在C++11 ...