Ribbon笔记

一、简介

Ribbon是Netflix出品的一套负载均衡组件,提供了许多Rule规则从负载列表中选取合适的server实例。

当实例出现问题时候,Riibbon本身具有自动移除问题实例的功能。

二、核心组件

组成部分职能
ServerServer 作为服务实例的表示,会记录服务实例的相关信息,如:服务地址,所属zone,服务名称,实例ID等
ServerList维护着一组Server实例列表,在应用运行的过程中,Ribbon通过ServerList中的服务实例供负载均衡器选择。ServerList维护列表可能在运行的过程中动态改变
ServerStats作为对应Server 的运行情况统计,一般是服务调用过程中的Server平均响应时间,累计请求失败计数,熔断时间控制等。一个ServerStats实例唯一对应一个Server实例
LoadBalancerStats作为 ServerStats实例列表的容器,统一维护
ServerListUpdater

负载均衡器通过ServerListUpdater来更新ServerList,

比如实现一个定时任务,每隔一段时间获取最新的Server实例列表

 

可以基于服务发现,也可以基于配置

 

ServerListUpdator只是定义了更新的方式,而具体怎么更新,则是封装成UpdateAction来操作的

Pinger

服务状态检验器,负责维护ServerList列表中的服务状态

注意:Pinger仅仅负责Server的状态,没有能力决定是否删除

PingerStrategy

定义以何种方式还检验服务是否有效,比如是按照顺序的方式还是并行的方式。

默认的PingStrategy,采用序列化的实现方式,依次检查服务实例是否可用

IPing

Ping,检验服务是否可用的方法,常见的是通过HTTP,或者TCP/IP的方式看服务有无认为正常的请求。

 

Spring Cloud集成下的IPing实现是NIWSDiscoveryPing。其使用Eureka作为服务注册和发现,则校验服务是否可用是通过监听Eureka 服务更新来更新Ribbon的Server状态

 1.ServerListFilter

ServerList负责维护服务实例,并使用ServerListFilter过滤器过滤出符合要求的服务实例列表List<Server>

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

Ribbon 的默认ServerListFilter实现:ZoneAffinityServerListFilter

Ribbon默认采取了区域优先的过滤策略,即当Server列表中,过滤出和当前实例所在的区域(zone)一致的server列表
与此相关联的,Ribbon有两个相关得配置参数: 

控制参数说明默认值
<service-name>.ribbon.EnableZoneAffinity是否开启区域优先false
<service-name>.ribbon.EnableZoneExclusivity是否采取区域排他性,即只返回和当前Zone一致的服务实例false
<service-name>.ribbon.zoneAffinity.maxLoadPerServer每个Server上的最大活跃请求负载数阈值0.6
<service-name>.ribbon.zoneAffinity.maxBlackOutServesrPercentage最大断路过滤的百分比0.8
<service-name>.ribbon.zoneAffinity.minAvailableServers最少可用的服务实例阈值2

 Ribbon 的ServerListFilter实现2:ZonePreferenceServerListFilter

ZonePreferenceServerListFilter 集成自 ZoneAffinityServerListFilter,在此基础上做了拓展,在 ZoneAffinityServerListFilter返回结果的基础上,再过滤出和本地服务相同区域(zone)的服务列表。
当指定了当前服务的所在Zone,并且 ZoneAffinityServerListFilter 没有起到过滤效果时,ZonePreferenceServerListFilter会返回当前Zone的Server列表。

Ribbon 的ServerListFilter实现3:ServerListSubsetFilter

这个过滤器作用于当Server数量列表特别庞大时(比如有上百个Server实例),这时,长时间保持Http链接也不太合适,可以适当地保留部分服务,舍弃其中一些服务,这样可使释放没必要的链接。
此过滤器也是继承自 ZoneAffinityServerListFilter,在此基础上做了拓展,在实际使用中不太常见,这个后续再展开介绍,暂且不表。

2. ServerStats

当LoadBalancer在选择合适的Server提供给应用后,应用会向该Server发送服务请求,则在请求的过程中,应用会根据请求的相应时间或者网络连接情况等进行统计;当应用后续从LoadBalancer选择合适的Server时,LoadBalancer 会根据每个服务的统计信息,结合Rule来判定哪个服务是最合适的。

统计的信息有:

ServerStats说明类型默认值
zone当前服务所属的可用区配置可通过 eureka.instance.meta.zone 指定
totalRequests总请求数量,client每次调用,数量会递增实时0
activeRequestsCountTimeout活动请求计数时间窗niws.loadbalancer.serverStats.activeRequestsCount.effectiveWindowSeconds,如果时间窗范围之内没有activeRequestsCount值的改变,则activeRequestsCounts初始化为0
 
配置60*10(seconds)
successiveConnectionFailureCount连续连接失败计数实时 
connectionFailureThreshold连接失败阈值通过属性niws.loadbalancer.default.connectionFailureCountThreshold 进行配置配置3
circuitTrippedTimeoutFactor断路器超时因子,niws.loadbalancer.default.circuitTripTimeoutFactorSeconds配置10(seconds)
maxCircuitTrippedTimeout最大断路器超时秒数,niws.loadbalancer.default.circuitTripMaxTimeoutSeconds配置30(seconds)
totalCircuitBreakerBlackOutPeriod累计断路器终端时间区间实时milliseconds
lastAccessedTimestamp最后连接时间实时 
lastConnectionFailedTimestamp最后连接失败时间实时 
firstConnectionTimestamp首次连接时间实时 
activeRequestsCount当前活跃的连接数实时 
failureCountSlidingWindowInterval失败次数统计时间窗配置1000(ms)
serverFailureCounts当前时间窗内连接失败的数量实时 
responseTimeDist.mean请求平均响应时间实时(ms)
responseTimeDist.max请求最大响应时间实时(ms)
responseTimeDist.minimum请求最小响应时间实时(ms)
responseTimeDist.stddev请求响应时间标准差实时(ms)
dataDist.sampleSizeQoS服务质量采集点大小实时 
dataDist.timestampQoS服务质量最后计算时间点实时 
dataDist.timestampMillisQoS服务质量最后计算时间点毫秒数,自1970.1.1开始实时 
dataDist.meanQoS 最近的时间窗内的请求平均响应时间实时 
dataDist.10thPercentileQoS 10% 处理请求的时间实时(ms)
dataDist.25thPercentileQoS 25% 处理请求的时间实时(ms)
dataDist.50thPercentileQoS 50% 处理请求的时间实时(ms)
dataDist.75thPercentileQoS 75% 处理请求的时间实时(ms)
dataDist.95thPercentileQoS 95% 处理请求的时间实时(ms)
dataDist.99thPercentileQoS 99% 处理请求的时间实时(ms)
dataDist.99.5thPercentileQoS 前99.5% 处理请求的时间实时(ms)

三、工作流程

1.LoadBalancer 选择服务实例的流程

LoadBalancer 选择服务实例的流程

1.通过ServerList获取当前可用的服务实例列表;
2.通过ServerListFilter将步骤1 得到的服务列表进行一次过滤,返回满足过滤器条件的服务实例列表;
3.应用Rule规则,结合服务实例的统计信息,返回满足规则的某一个服务实例;

通过上述的流程可以看到,实际上,在服务实例列表选择的过程中,有两次过滤的机会:第一次是首先通过ServerListFilter过滤器,另外一次是用过IRule 的选择规则进行过滤 

2.服务断路器的工作原理

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

ServerStats说明类型默认值
successiveConnectionFailureCount连续连接失败计数实时 
connectionFailureThreshold连接失败阈值通过属性niws.loadbalancer.default.connectionFailureCountThreshold 进行配置,当successiveConnectionFailureCount 超过了此限制时,将计算熔断时间配置3
circuitTrippedTimeoutFactor断路器超时因子,niws.loadbalancer.default.circuitTripTimeoutFactorSeconds配置10(seconds)
maxCircuitTrippedTimeout最大断路器超时秒数,niws.loadbalancer.default.circuitTripMaxTimeoutSeconds配置30(seconds)
totalCircuitBreakerBlackOutPeriod累计断路器终端时间区间实时milliseconds
lastAccessedTimestamp最后连接时间实时 
lastConnectionFailedTimestamp最后连接失败时间实时 
firstConnectionTimestamp首次连接时间实时 

 熔断时间的计算

1. 计算累计连接失败计数successiveConnectionFailureCount 是否超过 链接失败阈值connectionFailureThreshold。如果 successiveConnectionFailureCount < connectionFailureThreshold,即尚未超过限额,则熔断时间为 0 ;反之,如果超过限额,则进行步骤2的计算;
2.计算失败基数,最大不得超过 16:diff = (failureCount - threshold) > 16 ? 16 : (failureCount - threshold)
3.根据超时因子circuitTrippedTimeoutFactor计算超时时间: int blackOutSeconds = (1 << diff) * circuitTrippedTimeoutFactor.get();
4.超时时间不得超过最大超时时间`maxCircuitTrippedTimeout 上线,

当有链接失败情况出现断路逻辑时,将会最多:1<<16 * 10 =320s、最少1<<1 * 10 =100s 的请求熔断时间,再此期间内,此Server将会被忽略。
即:
熔断时间最大值:1<<16 * 10 =320s
熔断时间最小值:1<<1 * 10 =100s

熔断统计何时清空?

熔断的统计有自己的清除策略,当如下几种场景存在时,熔断统计会清空归零:

  1. 当请求时,发生的异常不是断路拦截类的异常(Exception)时(至于如何节点是否是断路拦截类异常,可以自定义)
  2. 当请求未发生异常,切且有结果返回时

 IRule从服务列表中,根据自身定义的规则,返回最合适的Server实例。而常见的规则是:

实现描述备注
RoundRobinRule通过轮询的方式,选择过程会有最多10次的重试机制 
RandomRule随机方式,从列表中随机挑选一个服务 
ZoneAvoidanceRule

基于ZoneAvoidancePredicate断言和AvailabilityPredicate断言的规则。ZoneAvoidancePredicate计算出哪个Zone的服务最差,然后将此Zone的服务从服务列表中剔除掉;

而AvaliabitiyPredicate是过滤掉正处于熔断状态的服务;

上述两个断言过滤出来的结果后,再通过RoundRobin轮询的方式从列表中挑选一个服务

 
BestAvailableRule最优匹配规则:从服务列表中给挑选出并发数最少的Server 
RetryRule采用了装饰模式,为Rule提供了重试机制 
WeightedResponseTimeRule基于请求响应时间加权计算的规则,如果此规则没有生效,将采用 RoundRobinRule的的策略选择服务实例 

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页