4.6 深入Ribbon

书籍地址: Spring Cloud 微服务架构开发实战

Ribbon 到底是通过什么机制来实现客户端负载均衡 ?
在实际应用中我们应该选择什么负载均衡 ?

4.6.1 Ribbon 客户端负载均衡原理

对于一个客户端负载均衡实现方案来说, 核心有一下3部分:

  • 服务发现: 能够自动发现所依赖服务的列表。
  • 服务监听: 能够检测到失效的服务,并高效的将失效服务从服务列表中剔除。
  • 服务选择策略: 也就是负载均衡策略,能够决定如何在多个服务实例中选择一个有效的服务实例。并进行相应的服务请求处理。

Ribbon作为Spring Cloud中客户端负载均衡实现方案,在具体实现上Ribbon 提供了下面6个组件:

4.6.1.1 服务器列表(ServerList)

服务器列表就是客户端负载均衡所使用的各服务的服务实例列表。Ribbon支持以下3种服务器列表方式。

  • 静态服务器列表: 可以通过Ribbon中的 BaseLoadBalancer 所提供的setServersList() 方法直接进行设置。
  • 基于配置的服务器列表:需要在项目配置文件中通过<服务名称>.ribbon.listOfServers 属性进行设置。
    userservice.ribbon.listOfServers=http://192.168.0.12:2100,http://192.168.0.12:21`0,http://192.168.0.12:2100 
    
  • 基于服务发现的服务器列表:当我们在应用中同时使用RibbonEureka时,默认就会使用该种方式,在应用启动时Ribbon 就会从Eureka服务器种获取所有注册服务的列表数据,并保持同步。
4.6.1.2 服务器列表过滤器(ServerListFilter)

当开发者使用动态服务器列表时,该组件会对原始服务列表使用一定策略进行过滤,并返回有效的服务器列表给客户端负载均衡器使用。Ribbon在具体实现上提供以下可用过滤器供开发者在应用种进行选择:

  • ZoneAffinityServerListFilter: 该过滤器基于区域感知的方式,实现对服务实例过滤,仅返回与本身所处趋于一致的服务提供者实例列表。
  • ServerListSubsetFilter: 该过滤器继承自 ZoneAffinityServerListFilter,在进行区域感知过滤后,仅返回一个固定大小的服务列表,也就是说不会返回全部符合条件的服务实例列表。默认返回20个服务实例。可通过 ribbon.ServerListSubsetFilter.size属性设置具体返回的服务实例个数。
  • ZonePreferenceServerListFilter: 是Spring Cloud整合 Netflix 时新增的过滤器,如果 EurekaRibbon 整合时,就会默认使用此过滤器。其主要是实现通过配置或者Eureka所属区域来过滤出同区域的服务实例列表。
4.6.1.3 服务实例存活探测(IPing)

服务实例存活探测,用来监测一个微服务实例是否有响应。Ribbon通过该组件来判断所持有的服务实例列表种的各服务可用情况。如果监测到某服务实例不再可用则会从列表中及时剔除。
Ribbon默认提供的服务如下:

  • PingUrl: 通过定期访问指定的URL,来判断服务器是否可用。
  • PingConstant: 不做任何处理,只是返回一个固定值,用来表示该服务是否可用,默认值时 true
  • NoOpPing: 不做任何处理,直接返回 true,表示该服务器可用。这是默认策略。
  • DummyPing: 直接返回true
  • NIWSDiscoveryPing: 根据 DiscoveryEnabledServerINstanceInfoInstanceStatus 属性判断,如果该属性的值为 InstanceStatus.UP, 则表示服务器可用,否则为不可用。
4.6.1.4 负载均衡策略(IRule)

负载均衡策略是负责选择一个最终服务实例地址作为负载均衡处理结果。Ribbon 提供的选择策略有 轮询根据相应时间加权断路器 等。

4.6.1.5 负载均衡器(LoadBalancer)

Ribbon 负载均衡的具体实现主要是通过 LoadBalancerClient 类来实现的,而 LoadBalancer 又将具体处理委托给ILoadBalancer来处理。
ILoadBalancer 通过配置 IRule,IPing等信息,并通过ServerList获取服务器注册列表的信息,默认每10秒,向服务列表中的每一个服务实例发送 ping 请求,检测服务实例是否仍存活,最后使用负载均衡策略对 ServerListFilter 过滤得到最终可用的服务实例列表进行处理,并获取到最终要调用的服务实例,然后交给服务调用器进行调用。

ILoadBalancer 也是一个接口,在具体实现上Ribbon提供了3个具体实现,分别是 DynamicServerListLoadBalancer, ZoneAwareLoadBalancernoOpLoadBalancer;
DynamicServerListLoadBalancer继承自ILoadBalancer 基础实现 BaseLoadBalancer, 在基础的负载均衡功能上增加了运行期间对服务实例动态更新和过滤的功能。
ZoneAwareLoadBalancer 继承自 DynamicServerListLoadBalancer,在其基础上知难而进该防止跨区域访问的问题,当我们使用Spring Cloud整合EurekaRibbon时,默认使用该实现。

4.6.1.6 服务调用器(RestClient)

服务调用器也就是负载均衡后,Ribbon向服务提供者发起REST请求的工具。

为何当我们在RestTemplate增加 @LoadBalance 注解后就可以为服务调用开启负载均衡处理呢?
这就是 LoadBalancerInterceptor的功劳了。当给 RestTemplate增加了 @LoadBalance注解后,LoadBalancerAutoConfiguration 就会对该RestTemplate 进行处理,在RestTemplate的拦截器列表中添加一个LoadBalancerInterceptor 拦截器,当通过 RestTemplate 进行服务请求时, LoadBalancerInterceptor 中的拦截方法就会启动,通过LoadBalancerClient使请求具有负载均衡功能。

4.6.2 负载均衡策略及配置

负载均衡策略主要负责从可用服务实例列表中选择一个,作为最终所要访问的服务实例。
以下为几种负载均衡策略:

  • RoundRobinRule: 轮询策略,Ribbon 以轮询的方式选择服务实例,即每次调用执行 i = (count + 1) mod n, 并选出第i台服务实例。其中 count 为执行请求的计数次数, n 为当前可用的服务器总个数。
  • **BestAvailableRule:**最大可用策略,即先过滤出故障服务实例后,选择一个当前并发请求数最小的。
  • WeightedResponseTimeRule: 带有加权的轮询策略,对各个服务实例响应时间进行加权处理,然后再采用轮询的方式获取相应的服务实例。
  • AvailabilityFilteringRule: 可用过滤策略,先过滤出有故障的或并发请求大于阈值的一部分服务实例。然后再以线性轮询的方式从过滤后的实例清单中选出一个实例。
  • ZoneAvoidanceRule: 区域感知策略,先使用主过滤条件(区域负载器,选择最优区域)对所有实例过滤并返回过滤后的实例清单,依次使用次过滤条件列表中的过滤条件对主过滤条件的结果进行过滤,判断最小过滤数(默认1)和最小过滤百分比(默认0),最后对满足条件的服务实例则使用RoundRobinRule(轮询方式)方式选择一个,这个策略可以降低服务之间的调用延迟,提升系统效率。

一般我们可以通过项目配置文件 的属性配置进行设置:

#这里我们将用户服务负载均衡策略配置为 ZoneAvoidanceRule
 userservice.ribbon.NFLoadNalancerRuleClassName=com.netflix.loadbalancer.ZoneAvoidanceRule
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值