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