导航

1. 概述

Ribbon实现客户端的负载均衡。Spring cloud Feign已经默认集成Ribbon。这是我开始学习ribbon和fegin迷惑的地方,为什么很多文章都先讲了ribbon,然后直接讲feign,但是没有提到Fegin和ribbon的关系。

本文的主要的内容如下

  • 1.ribbon功能说明
  • 2.ribbon的6个主要组件:IRule、IPing、ServerList 、ServerListFilter、ServerListUpdater、ILoadBalancer
  • 3.ribbon通过属性文件配置ribbon

2. Ribbon功能说明

Ribbon实现客户端的负载均衡,负载均衡器提供很多对http和tcp的行为控制。Spring cloud Feign已经集成Ribbon,所以注解@FeignClient的类,默认实现了ribbon的功能。

Ribbon主要包括如下功能

  • 1.支持通过DNS和IP和服务端通信
  • 2.可以根据算法从多个服务中选取一个服务进行访问
  • 3.通过将客户端和服务器分成几个区域(zone)来建立客户端和服务器之间的关系。客户端尽量访问和自己在相同区域(zone)的服务,减少服务的延迟
  • 4.保留服务器的统计信息,ribbon可以实现用于避免高延迟或频繁访问故障的服务器
  • 5.保留区域(zone)的统计数据,ribbon可以实现避免可能访问失效的区域(zone)

3. Ribbon主要组件

Ribbon主要包含如下组件:

  • 1.IRule
  • 2.IPing
  • 3.ServerList
  • 4.ServerListFilter
  • 5.ServerListUpdater
  • 6.IClientConfig
  • 7.ILoadBalancer

3.1. IRule

功能:根据特定算法中从服务列表中选取一个要访问的服务 常用IRule实现有以下几种:

RoundRobinRule 
轮询规则,默认规则。同时也是更高级rules的回退策略

AvailabilityFilteringRule 
这个负载均衡器规则,会先过滤掉以下服务:

  • a. 由于多次访问故障而处于断路器跳闸状态
  • b. 并发的连接数量超过阈值

然后对剩余的服务列表按照RoundRobinRule策略进行访问

WeightedResponseTimeRule 
根据平均响应时间计算所有服务的权重,响应时间越快,服务权重越重、被选中的概率越高。刚启动时,如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够,会切换到WeightedResponseTimeRule。

RetryRule 
先按照RoundRobinRule的策略获取服务,如果获取服务失败,则在指定时间内会进行重试,获取可用的服务

BestAvailableRule 
此负载均衡器会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务

RandomRule 
随机获取一个服务

3.2. IPing

功能:在后台运行的一个组件,用于检查服务列表是否都活

NIWSDiscoveryPing 
不执行真正的ping。如果Discovery Client认为是在线,则程序认为本次心跳成功,服务活着

PingUrl 
此组件会使用HttpClient调用服务的一个URL,如果调用成功,则认为本次心跳成功,表示此服务活着。

NoOpPing 
永远返回true,即认为服务永远活着

DummyPing 
默认实现,默认返回true,即认为服务永远活着

3.3. ServerList

功能:存储服务列表。分为静态和动态。如果是动态的,后台有个线程会定时刷新和过滤服务列表

常用ServerList 实现有以下几种:

ConfigurationBasedServerList 
从配置文件中获取所有服务列表

配置例子:

sample-client.ribbon.listOfServers=www.microsoft.com:80,www.yahoo.com:80,www.google.com:80

DiscoveryEnabledNIWSServerList 
从Eureka Client中获取服务列表。此值必须通过属性中的VipAddress来标识服务器集群。DynamicServerListLoadBalancer会调用此对象动态获取服务列表

DomainExtractingServerList 
代理类,根据ServerList的值实现具体的逻辑

3.4. ServerListFilter

该接口允许过滤配置或动态获取的具有所需特性的服务器列表。ServerListFilter是DynamicServerListLoadBalancer用于过滤从ServerList实现返回的服务器的组件。

常用ServerListFilter 实现有以下几种:

ZoneAffinityServerListFilter 
过滤掉所有的不和客户端在相同zone的服务,如果和客户端相同的zone不存在,才不过滤不同zone有服务。

启用此配置使用以下配置

<clientName>.ribbon.EnableZoneAffinity=true

ZonePreferenceServerListFilter 
ZoneAffinityServerListFilter的子类。和ZoneAffinityServerListFilter相似,但是比较的zone是发布环境里面的zone。过滤掉所有和客户端环境里的配置的zone的不同的服务,如果和客户端相同的zone不存在,才不进行过滤。

ServerListSubsetFilter 
ZoneAffinityServerListFilter的子类。此过滤器确保客户端仅看到由ServerList实现返回的整个服务器的固定子集。 它还可以定期用新服务器替代可用性差的子集中的服务器。

要启用此过滤器,请指定以下属性:

<clientName>.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList 
# the server must register itself with Eureka server with VipAddress "myservice"
<clientName>.ribbon.DeploymentContextBasedVipAddresses=myservice
<clientName>.ribbon.NIWSServerListFilterClassName=com.netflix.loadbalancer.ServerListSubsetFilter
# only show client 5 servers. default is 20.
<clientName>.ribbon.ServerListSubsetFilter.size=5

3.5. ServerListUpdater

功能:被DynamicServerListLoadBalancer用于动态的更新服务列表。 常用的实现类:

PollingServerListUpdater 
默认的实现策略。此对象会启动一个定时线程池,定时执行更新策略

EurekaNotificationServerListUpdater 
当收到缓存刷新的通知,会更新服务列表。

3.6. IClientConfig

功能: 定义各种配置信息,用来初始化ribbon客户端和负载均衡器

常用IClientConfig实现有以下几种: 
DefaultClientConfigImpl 
IClientConfig的默认实现,配置文件里的部分值为ribbon。

3.7. ILoadBalancer

定义软件负载平衡器操作的接口。动态更新一组服务列表及根据指定算法从现有服务器列表中选择一个服务

DynamicServerListLoadBalancer 
DynamicServerListLoadBalancer组合Rule、IPing、ServerList、ServerListFilter、ServerListUpdater 实现类,实现动态更新和过滤更新服务列表

ZoneAwareLoadBalancer 
这是DynamicServerListLoadBalancer的子类,主要加入zone的因素。统计每个zone的平均请求的情况,保证从所有zone选取对当前客户端服务最好的服务组列表

4. 通过属性文件配置ribbon的主要组件

除了可以使用编程方式创建外,ribbon也提供通过反射和配置属性文件来实现对应的功能。

4.1. 根据属性文件配置ribbon

配置属性的格式如下:

<clientName>.<nameSpace>.<propertyName>=<value>
 1. <clientName>:这是调用ribbon的客户端名称,如果此值为没有配置,则此条属性会作用到所有的客户端。
 2. <nameSpace>:默认值为 “ribbon”
 3. <propertyName>:所有的可用的属性都在com.netflix.client.conf.CommonClientConfigKey。

如果你没有配置任何属性,则ribbon会使用com.netflix.client.config.DefaultClientConfigImpl里的值。反之,则会使用你配置的值替换默认的值

下面是对客户端名称为”sample-client”配置属性的demo

# Max number of retries on the same server (excluding the first try)
sample-client.ribbon.MaxAutoRetries=1

# Max number of next servers to retry (excluding the first server)
sample-client.ribbon.MaxAutoRetriesNextServer=1

# Whether all operations can be retried for this client
sample-client.ribbon.OkToRetryOnAllOperations=true

# Interval to refresh the server list from the source
sample-client.ribbon.ServerListRefreshInterval=2000

# Connect timeout used by Apache HttpClient
sample-client.ribbon.ConnectTimeout=3000

# Read timeout used by Apache HttpClient
sample-client.ribbon.ReadTimeout=3000

# Initial list of servers, can be changed via Archaius dynamic property at runtime
sample-client.ribbon.listOfServers=www.microsoft.com:80,www.yahoo.com:80,www.google.com:80

4.2. 通过配置文件配置Ribbon的主要组件

使用以下属性值可以配置ribbon组合接口使用哪个具体的实现类,xx表示类的全限定名称,这里略:

<clientName>.<nameSpace>.NFLoadBalancerClassName=xx
<clientName>.<nameSpace>.NFLoadBalancerRuleClassName=xx
<clientName>.<nameSpace>.NFLoadBalancerPingClassName=xx
<clientName>.<nameSpace>.NIWSServerListClassName=xx
<clientName>.<nameSpace>.NIWSServerListFilterClassName=xx

4.3 Spring Cloud Netflix 提供默认的ribbon实现类

IClientConfig ribbonClientConfig: DefaultClientConfigImpl 
IRule ribbonRule: ZoneAvoidanceRule 
IPing ribbonPing: DummyPing 
ServerList ribbonServerList: ConfigurationBasedServerList 
ServerListFilter ribbonServerListFilter: ZonePreferenceServerListFilter 
ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer 
ServerListUpdater ribbonServerListUpdater: PollingServerListUpdater

 

 

本文转载自 https://juejin.im/post/5d68b73af265da03b12061be