Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Spring Cloud中负载均衡器概览

Spring Cloud中负载均衡器概览

作者头像
江南一点雨
发布于 2018-04-02 07:45:57
发布于 2018-04-02 07:45:57
1K00
代码可运行
举报
文章被收录于专栏:玩转JavaEE玩转JavaEE
运行总次数:0
代码可运行

在上篇文章中(RestTemplate的逆袭之路,从发送请求到负载均衡)我们完整的分析了RestTemplate的工作过程,在分析的过程中,我们遇到过一个ILoadBalancer接口,这个接口中有一个chooseServer方法是我们选择服务实例的方法,这个也是整个负载均衡中最最核心的部分,那么它到底是采用了什么样的策略从服务提供者列表中选出了一个服务供服务消费者去调用的?这是我们今天要讨论的问题,本文我主要是想基于互联网上公开的资料,来对Spring Cloud中提供的负载均衡器做一个简明扼要的介绍。


负载均衡器

首先我们来看一张上篇文章中的旧图:

这是ILoadBalancer接口的一张类关系图,我们就从这张图里看起吧。

AbstractLoadBalancer

AbstractLoadBalancer类的定义如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public abstract class AbstractLoadBalancer implements ILoadBalancer {

    public enum ServerGroup{
        ALL,
        STATUS_UP,
        STATUS_NOT_UP        
    }
    public Server chooseServer() {
        return chooseServer(null);
    }
    public abstract List<Server> getServerList(ServerGroup serverGroup);
    public abstract LoadBalancerStats getLoadBalancerStats();    
}

关于这个类我说以下几点: 1. AbstractLoadBalancer实现了ILoadBalancer接口,但它是一个抽象类,它里边定义了一个关于服务实例的分组枚举类,包含了三种类型的服务:ALL表示所有服务,STATUS_UP表示正常运行的服务,STATUS_NOT_UP表示下线的服务。 2. chooseServer方法毫无疑问是用来选取一个服务实例,但是要怎么选这里并没有说,我们以后在它的实现类里边寻找选取策略。 3. getServerList方法用来获取某一个分组中所有的的服务实例。 4. getLoadBalancerStats方法用来获取LoadBalancerStats对象,LoadBalancerStats对象中保存了每一个服务的所有细节信息。

BaseLoadBalancer

BaseLoadBalancer是AbstractLoadBalancer的一个实现类,源码比较长我就不贴出来的,我们在这里主要来说说BaseLoadBalancer提供了哪些功能:

1. 首先这个类中有两个List集合中放的Server对象,一个List集合用来保存所有的服务实例,还有一个List集合用来保存当前有效的服务实例。 2. BaseLoadBalancer中定义了一个IPingStrategy,用来描述服务检查策略,IPingStrategy默认实现采用了SerialPingStrategy实现,SerialPingStrategy中的pingServers方法就是遍历所有的服务实例,一个一个发送请求,查看这些服务实例是否还有效,如果网络环境不好的话,这种检查策略效率会很低,如果我们想自定义检查策略的话,可以重写SerialPingStrategy的pingServers方法。 3. 在BaseLoadBalancer的chooseServer方法中(负载均衡的核心方法),我们发现最终调用了IRule中的choose方法来找到一个具体的服务实例,IRule是一个接口,在BaseLoadBalancer它的默认实现是RoundRobinRule类,RoundRobinRule类中采用了最常用的线性负载均衡规则,也就是所有有效的服务端轮流调用。 4. 在BaseLoadBalancer的构造方法中会启动一个PingTask,这个PingTask用来检查Server是否有效,PingTask的默认执行时间间隔为10秒。 5. markServerDown方法用来标记一个服务是否有效,标记方式为调用Server对象的setAlive方法设置isAliveFlag属性为false。 6. getReachableServers方法用来获取所有有效的服务实例列表。 7. getAllServers方法用来获取所有服务的实例列表。 8. addServers方法表示向负载均衡器中添加一个新的服务实例列表。

BaseLoadBalancer的功能大概就这么多。

DynamicServerListLoadBalancer

DynamicServerListLoadBalancer是BaseLoadBalancer的一个子类,在DynamicServerListLoadBalancer中对基础负载均衡器的功能做了进一步的扩展,我们来看看。

1. 首先DynamicServerListLoadBalancer类一开始就声明了一个变量serverListImpl,serverListImpl变量的类型是一个ServerList<T extends Server>,这里的泛型得是Server的子类,ServerList是一个接口,里边定义了两个方法:一个getInitialListOfServers用来获取初始化的服务实例清单;另一个getUpdatedListOfServers用于获取更新的服务实例清单。 2. ServerList接口有很多实现类,DynamicServerListLoadBalancer默认使用了DomainExtractingServerList类作为ServerList的实现,但是在DomainExtractingServerList的构造方法中又传入了DiscoveryEnabledNIWSServerList对象,查看源码发现最终两个清单的获取方式是由DiscoveryEnabledNIWSServerList类来提供的。 3. DomainExtractingServerList类中的obtainServersViaDiscovery方法是用来发现服务实例并获取的,obtainServersViaDiscovery方法的主要逻辑是这样:首先依靠EurekaClient从服务注册中心获取到具体的服务实例InstanceInfo列表,然后对这个列表进行遍历,将状态为UP的实例转换成DiscoveryEnabledServer对象并放到一个集合中,最后将这个集合返回。 4. DynamicServerListLoadBalancer中还定义了一个ServerListUpdater.UpdateAction类型的服务更新器,Spring Cloud提供了两种服务更新策略:一种是PollingServerListUpdater,表示定时更新;另一种是EurekaNotificationServerListUpdater表示由Eureka的事件监听来驱动服务列表的更新操作,默认的实现策略是第一种,即定时更新,定时的方式很简单,创建Runnable,调用DynamicServerListLoadBalancer中updateAction对象的doUpdate方法,Runnable延迟启动时间为1秒,重复周期为30秒。 5. 在更新服务清单的时候,调用了我们在第一点提到的getUpdatedListOfServers方法,拿到实例清单之后,又调用了一个过滤器中的方法进行过滤。过滤器的类型有好几种,默认是DefaultNIWSServerListFilter,这是一个继承自ZoneAffinityServerListFilter的过滤器,具有区域感知功能。即它会对服务提供者所处的Zone和服务消费者所处的Zone进行比较,过滤掉哪些不是同一个区域的实例。

综上,DynamicServerListLoadBalancer主要是实现了服务实例清单在运行期间的动态更新能力,同时提供了对服务实例清单的过滤功能。

ZoneAwareLoadBalancer

ZoneAwareLoadBalancer是DynamicServerListLoadBalancer的子类,ZoneAwareLoadBalancer的出现主要是为了弥补DynamicServerListLoadBalancer的不足。由于DynamicServerListLoadBalancer中并没有重写chooseServer方法,所以DynamicServerListLoadBalancer中负责均衡的策略依然是我们在BaseLoadBalancer中分析出来的线性轮询策略,这种策略不具备区域感知功能,这样当需要跨区域调用时,可能会产生高延迟。ZoneAwareLoadBalancer重写了setServerListForZones方法,该方法在其父类中的功能主要是根据区域Zone分组的实例列表,为负载均衡器中的LoadBalancerStats对象创建ZoneStats并存入集合中,ZoneStats是一个用来存储每个Zone的状态和统计信息。重写之后的setServerListForZones方法主要做了两件事:一件是调用getLoadBalancer方法来创建负载均衡器,同时创建服务选择策略;另一件是对Zone区域中的实例清单进行检查,如果对应的Zone下已经没有实例了,则将Zone区域的实例列表清空,防止节点选择时出现异常。

OK,以上就是我们对负载均衡器的一个简单介绍,下一篇文章我们将继续介绍负载均衡策略

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-09-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 江南一点雨 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【DB笔试面试608】在Oracle中,如何使用STA来生成SQL Profile?
利用STA对语句进行优化后,STA会对语句进行分析,采用最优的优化策略,并给出优化后的查询计划。可以按照STA给出的建议重写语句。但是,有些情况下,你可能无法重写语句(比如在生产环境中,SQL语句又在一个包中)。这个时候就可以利用Sql Profile,将优化策略存储在Profile中,Oracle在构建这条语句的查询计划时,就不会使用已有相关统计数据,而使用Profile的策略,生成新的查询计划。
AiDBA宝典
2019/09/29
2.8K0
【DB笔试面试608】在Oracle中,如何使用STA来生成SQL Profile?
Oracle 19c 新特性:ADG的自动DML重定向增强读写分离
在前面的文章《Oracle 19c 十大新特性一览》中,我们曾经提到 Oracle 19c的一个重要增强,就是ADG的自动DML转发:
数据和云
2019/03/07
1.4K0
Oracle 19c 新特性:ADG的自动DML重定向增强读写分离
关于权限设置的一个小把戏(r2第27天)
现在有一个需求,需要开放一些"特殊“的权限给开发组。 具体的背景是这样的: 有三个数据库用户,tabowner, tabconn, tab_temp三个用户 tableowner是owner用户,里面存放着表,索引,序列,存储过程等。 tabconn是一个连接用户,在这个用户里面建立了一些同义词,可以直接通过这个用户来进行数据的增删改查。 tab_temp是一个临时的连接用户,通过这个用户只能查询一些有限的信息,不能进行数据的改动。而且不能执行select sequence_name.nextval fro
jeanron100
2018/03/14
5610
ORA-00942: table or view does not exist
      在过程,包,函数,触发器中调用Oracle相关动态性能视图时,需要授予适当的权限,否则会收到表和视图不存在的错误提示。即使你可以单独查询这些视图。因为动态性能视图依赖于底层表,无法直接对其授予权限。下面就是这个现象相关的例子。
Leshami
2018/08/13
2K0
Oracle 18c新特性:Schema-Only 帐号提升应用管理安全性
在 Oracle 18c 中,一个特殊类型的帐号被引入到数据库当中,这特特性被称为 Schema-Only 帐号,这个帐号通过 NO AUTHENTICATION 语句建立,没有密码,也就不允许直接登录,所以这种帐号类型是 纯模式类型。
数据和云
2018/12/07
6630
Oracle 18c新特性:Schema-Only 帐号提升应用管理安全性
SQL基础--> 序列(SEQUENCE)、同义词(SYNONYM)
--=============================================
Leshami
2018/08/07
1.4K0
有关Oracle role的总结
oracle的role算是对sys privilege 和object privilege的打包。 今天深入的测试了下,还算有不少的东西。 role不是schema对象 像table等在一个schema里面不能有同名的schema object,但是可以有同名的table和role,如下。 SQL> conn test1/test1 Connected. SQL> create role testrole; Role created. SQL> create table testrole as select
jeanron100
2018/03/13
1.1K0
【DB笔试面试604】在Oracle中,存储概要(Stored Outline)的作用是什么?
OUTLINE的原理是将调好的执行计划(一系列的Hint)保存起来,然后使用该效率高的执行计划替换之前效率低下的执行计划,从而使得当系统每次执行该SQL时,都会使用已存储的执行计划来执行。所以,可以在不改变已有系统SQL的情况下达到改变其执行计划的目的。OUTLINE方式是通过存储Hint的方式来达到执行计划的稳定与改变。当发现低效SQL之后,可以使用Hint优化它,对于SQL代码可以修改的情况,直接修改SQL代码加上Hint即可。
AiDBA宝典
2019/09/29
1.1K0
【OCP最新题库解析(052)--题49】Examine these facts about a database.
该系列专题为2018年4月OCP-052考题变革后的最新题库。题库为小麦苗解答,若解答有不对之处,可留言,也可联系小麦苗进行修改。
AiDBA宝典
2019/09/29
4470
【OCP最新题库解析(052)--题36】USER1 grants SELECT, INSERT, and UPDATE p
SQL> REVOKE UPDATE ON user1.emp FROM user1;
AiDBA宝典
2019/09/29
5530
Oracle海量数据优化-01分区的渊源
当我们看到这条语句时,会想到什么呢? 一条再简单不过的按照条件删除数据库的操作。 如果大量存在,会不会引起系统性能问题呢?
小小工匠
2021/08/16
3970
通过闪回事务查看数据dml的情况 (r2笔记69天)
昨天有一个网友问我,怎么能够查询一个表中最后一条插入的记录,我大概回复了,可以通过闪回事务来实现,但是得看什么时候插入的数据,也需要一定的运气。 如果通过闪回事务来得到对应的undo_sql,可能多个dml语句对应一个事务,所以我们需要得到的是一个完整的事务的信息,里面包括对应的Undo_sql,这样才算得到比较完整的sql语句。 我在本地自己做了一个测试。 创建一个test表,然后插入一些记录,然后尝试修改一些数据。 SQL> DROP TABLE TEST; Table dropped. SQL>
jeanron100
2018/03/14
5250
impdp数据泵导入使用table_exists_action=SKIP存在的问题及如何接着导入后续的索引等信息
数据泵已经跑了8个小时了,而且表的数据都已经入库了,就剩后边的索引、约束和触发器等,那难道我还得重新从头接着导入吗?答案不是的,我们有办法,就是结合“table_exists_action=SKIP content=metadata_only sqlfile=index.sql”这几个参数来解决。
AiDBA宝典
2023/04/27
1.9K0
impdp数据泵导入使用table_exists_action=SKIP存在的问题及如何接着导入后续的索引等信息
关于虚拟索引的学习(r3笔记第75天)
昨天简单总结了下不可见索引,今天来说说虚拟索引。 这两个索引听起来有点类似。其实差别还是比较大。 不可见索引有对应的索引段,而虚拟索引没有对应的索引段存在。 不可见索引可以通过alter语句来直接切换可见不可见。而对于虚拟索引而言这些操作都不支持。 不可见索引可以在user_indexes中查到对应的数据字典信息。但是虚拟索引在user_indexes中都没有记录,最后只能从dba_objects里面勉强查到一条它存在的记录。 不可见索引和虚拟索引都有对应的数据库参数,可以通过a
jeanron100
2018/03/15
6930
Oracle 20c 新特性:区块链表的加密HASH以及删除保护
关于 Oracle 20c 区块链表(Blockchain Table),很多朋友表达了强烈的关注,通过一些基本测试,我们能够揭示关于区块链表的工作原理。
数据和云01
2020/04/01
5490
Oracle 20c 新特性:区块链表的加密HASH以及删除保护
Oracle基础维护01-常用管理命令总结
此时,sga和pga自动调整,sga_target最小为4M,pga_aggregate_target最小为1M;
Alfred Zhao
2019/05/24
4600
史上最全-oracle12c pdb迁移实践
Oracle在12c版本引入了多租户的概念,在一个cdb的根容器下可以创建多个pdb供不同用户使用,cdb中主要保存数据库元数据,而pdb中保存用户数据,各个pdb直接不相互影响。Oracle提供了多种方式进行pdb数据库的创建/迁移/克隆,甚至实现了不停机的在线克隆。
数据库架构之美
2019/12/18
2.4K0
史上最全-oracle12c pdb迁移实践
Oracle 11g 单实例到单实例OGG同步实施文档-RMAN 初始化
当所有在Extract 启动之前的开始的交易都完成后,我们就可以使用RMAN 备份生产 端的数据库了。备份数据库的过程中一定要密切监控Extract 进程的状态,保证其一 直正常运行:
星哥玩云
2022/08/18
7160
关于物化视图疑问(32天)
--初始化操作, 创建两个用户一个,testo,一个test. 在testo上创建表,test上创建物化视图。 SQL> create user testo identified by testo; User created. SQL> create user test identified by test; User created. SQL> grant connect,resource to testo,test; Grant succeeded. SQL> grant create materia
jeanron100
2018/03/13
1K0
oracle查看密码修改记录_oracle查询数据库用户密码到期时间
ORA-01920: user name ‘T1’ conflicts with another user or role name
全栈程序员站长
2022/09/19
3K0
推荐阅读
相关推荐
【DB笔试面试608】在Oracle中,如何使用STA来生成SQL Profile?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验