美文网首页Spring cloud
SpringCloud-Ribbon-03设计原理

SpringCloud-Ribbon-03设计原理

作者: 小亮__ | 来源:发表于2019-06-24 07:22 被阅读11次

Ribbon的核心是基于LoadBalancer负载均衡器来实现的,Ribbon通过ILoadBalancer接口对外提供统一的选择服务器(Server)的功能基础接口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();
}

其中LoadBalancer内部有如下图的模块组成:


LoadBalancer模块图

ServerList模块

主要是负责维护server列表(新增,更新,删除),接口如下:

public interface ServerList<T extends Server> {
    //获取初始化的服务列表
    public List<T> getInitialListOfServers();
    // 获取更新后的的服务列表
    public List<T> getUpdatedListOfServers();   
}

实现方式分以下两类,并可以通过<service-name>.ribbon.NIWSServerListClassName,来配置具体的实现方式

  • 基于配置文件:通过配置文件,静态地配置服务器列表,可以使用netflix archaius框架动态监控配置文件的变化,来更新ServerList 信息,通过以下配置开启
    <service name>.ribbon.NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList
    
  • 基于服务发现:结合服务发现组件如consul或eureka,实现动态更新服务列表,通过以下配置开启
     <service name>.ribbon.NIWSServerListClassName=com.netflix.loadbalancer.DiscoveryEnabledNIWSServerList
    

ServerListUpdater模块

负责在运行时,动态的更新服务状态的方式,可以通过配置<service-name>.ribbon.ServerListUpdaterClassName设置,当前有如下两种实现方式:

  • 基于定时任务的拉取
    <service-name>.ribbon.ServerListUpdaterClassName=com.netflix.loadbalancer.PollingServerListUpdater
    
  • 基于Eureka服务事件通知
    <service-name>.ribbon.ServerListUpdaterClassName=com.netflix.loadbalancer.EurekaNotificationServerListUpdater
    

ribbon在默认情况下,会采用基于配置的服务列表维护,定时任务按时拉取服务列表的方式,频率为30s.

ServerListFilter模块

ServerListFilter的职能很简单,传入一个服务实例列表,过滤出满足过滤条件的服务列表

public interface ServerListFilter<T extends Server> {
    public List<T> getFilteredListOfServers(List<T> servers);
}

ZoneAffinityServerListFilterRibbon:Ribbon 的默认ServerListFilter实现,采取了区域优先的过滤策略,与其相关的配置如下

# 是否开启区域优先,默认false
<service-name>.ribbon.EnableZoneAffinity=false
# 是否采取区域排他性,即只返回和当前Zone一致的服务实例
<service-name>.ribbon.EnableZoneExclusivity=false

ZonePreferenceServerListFilter:继承 ZoneAffinityServerListFilter,在其上增加了扩展,在其返回结果的基础上,再过滤出和本地服务相同区域(zone)的服务列表。
ServerListSubsetFilter:继承 ZoneAffinityServerListFilter,这个过滤器作用于当Server数量列表特别庞大时(比如有上百个Server实例),这时,长时间保持Http链接也不太合适,可以适当地保留部分服务,舍弃其中一些服务,这样可使释放没必要的链接。

ServerStats模块

ServerStats中记录这server的状态信息,如下

# 当前服务所属的可用区
zone
#总请求数量,client每次调用,数量会递增
totalRequests
#活动请求计数时间窗
activeRequestsCountTimeout
#连续连接失败计数
successiveConnectionFailureCount
#连接失败阈值通过属性
connectionFailureThreshold
#断路器超时因子
circuitTrippedTimeoutFactor
#最大断路器超时秒数
maxCircuitTrippedTimeout
#最后连接时间
lastAccessedTimestamp
#最后连接失败时间
lastConnectionFailedTimestamp
# 首次连接时间
firstConnectionTimestamp
....等其他信息

断路器:当有某个服务存在多个实例时,在请求的过程中,负载均衡器会统计每次请求的情况(请求相应时间,是否发生网络异常等),当出现了请求出现累计重试时,负载均衡器会标识当前服务实例,设置当前服务实例的断路的时间区间,在此区间内,当请求过来时,负载均衡器会将此服务实例从可用服务实例列表中暂时剔除,优先选择其他服务实例,可以通过以下参数设置断路器信息

# 连续连接失败计数
successiveConnectionFailureCount
#连接失败阈值,默认3超过则熔断
connectionFailureThreshold
#断路器超时因子
circuitTrippedTimeoutFactor
#最大断路器超时秒数
maxCircuitTrippedTimeout
....等其他信息

IPing ,IPingStrategy 接口

IPing用来检测Server是否可用,ILoadBalancer的实现类维护一个Timer每隔10s检测一次Server的可用状态,其核心方法有:

public interface IPing {
    //检测服务是否存活
    public boolean isAlive(Server server);
}

/**
* 定义Ping服务状态是否有效的策略,是序列化顺序Ping,还是并行的方式Ping,在此过程中,应当保证相互不受影响
 */
public interface IPingStrategy {
    boolean[] pingServers(IPing ping, Server[] servers);
}

默认情况下,负载均衡器内部会创建一个周期性定时任务,检查server是否存活,相关配置参数如下

# Ping定时任务周期,默认30s
<service-name>.ribbon.NFLoadBalancerPingInterval=30
#Ping超时时间,默认2s
<service-name>.ribbon.NFLoadBalancerMaxTotalPingTime=2
# IPing实现类,Spring Cloud集成下的IPing实现:NIWSDiscoveryPing,
# 其使用Eureka作为服务注册和发现,则校验服务是否可用,则通过监听Eureka 服务更新来更新Ribbon的Server状态
<service-name>.ribbon.NFLoadBalancerPingClassName=

IRule 接口

IRule是负载均衡策略的抽象,ILoadBalancer通过调用IRule的choose()方法返回Server,其核心方法如下:

public interface IRule{
   // 从负载均衡器中选择一个实例
    public Server choose(Object key);
    // 设置ILoadBalancer 
    public void setLoadBalancer(ILoadBalancer lb);
    public ILoadBalancer getLoadBalancer();    
}

以下是具体实现类,我们也可以自定义自己的负载均衡策略


相关文章

  • SpringCloud-Ribbon-03设计原理

    Ribbon的核心是基于LoadBalancer负载均衡器来实现的,Ribbon通过ILoadBalancer接口...

  • RTOS基础(邮箱)

    邮箱的原理与创建 问题概述 设计原理 设计实现 邮箱的获取和释放 设计原理 设计实现 邮箱的清空与删除 设计原理 ...

  • RTOS基础(其他)

    堆栈使用量测量 问题概述 设计原理 设计实现 CPU百分比 设计需求 设计原理 设计实现 内核裁剪 设计原理 Ho...

  • RTOS(事件标志组)

    事件标志组的原理与创建 问题概述 设计原理 设计实现 事件标志组的等待与通知 设计需求 设计原理 设计实现 事件标...

  • 汽车电子硬件开发规范

    1 原理图设计流程 原理图设计是从系统设计到硬件细节设计的基础,细节设计是“系统框图-原理图-电路版图”不断设计的...

  • RTOS基础(存储块)

    存储块的原理与创建 问题概述 设计原理 设计实现 存储块的获取与释放 设计原理 设计实现 存储块的删除和状态查询 ...

  • RTOS基础(计数信号量)

    计数信号量的原理与创建 概述 设计原理 设计实现 计数信号量的获取与释放 设计原理 设计实现 计数信号的删除与状态...

  • 【读书】《银行4.0》第一性原理和iPhone设计

    第一性原理,与类比设计和微设计不同,第一性原理回归问题的本源,回归设计的本质——设计是为了什么。 第一性原理设计的...

  • 缓存设计

    目录 缓存设计需要考虑的地方 项目代码编写 mybaits缓存设计原理 guava缓存设计原理 本地缓存设计需要考...

  • •设计原理•读书笔记

    1、设计原理的作用 设计原理是为了帮助设计师,而不是限制设计师的创造力。设计师要在熟悉原理的基础上理解它们,这样在...

网友评论

    本文标题:SpringCloud-Ribbon-03设计原理

    本文链接:https://www.haomeiwen.com/subject/mrsiqctx.html