Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它基于 Netflix Ribbon 实现,通过 Spring Cloud Ribbon 的封装,在微服务架构中使用客户端负载均衡调用非常简单。Ribbon 是 Spring Cloud 整个大家庭中相对而言比较复杂的模块,直接影响到服务调度的质量和性能。
一、客户端负载均衡
负载均衡是对系统的高可用、网络压力的缓解和处理能力扩容的重要手段之一。负载均衡分为:
- 服务端负载均衡,又分为硬件负载均衡(比如 F5)、软件负载均衡(比如 Nginx)
- 客户端负载均衡(比如 Ribbon)
(1)服务端负载均衡:维护一个可用的服务端清单,通过心跳检测来剔除故障的服务端节点,保证清单中都是可正常访问的服务端节点。当客户端发送请求到负载均衡设备的时候,该设备按某种算法(轮询、加权等)从维护的可用服务端清单中取出一台服务端端地址,然后进行转发。
(2)客户端负载均衡:和服务端负载均衡最大的不同点在于服务清单所存储的位置。在客户端负载均衡中,所有客户端节点都维护着自己要访问的服务端清单,而这些服务端端清单来自于服务注册中心。
二、和 feign 的集成实现方式
在和 Feign 结合的场景下,最终请求会转发成 http://< 服务名称 >/<relative-path-to-service> 的格式,通过 LoadBalancerFeignClient,
提取出服务标识 < 服务名称 >,然后根据服务名称在上下文中查找对应服务的负载均衡器 FeignLoadBalancer。负载均衡器负责根据既有的服务实例的统计信息,挑选出最合适的服务实例。
三、原理
(1)Ribbon 通过 ILoadBalancer 接口对外提供统一的选择服务器 (Server) 的功能,此接口会根据不同的负载均衡策略 (IRule) 选择合适的 Server 返回给使用者。
public interface ILoadBalancer {void addServers(List<Server> var1);
Server chooseServer(Object var1);
void markServerDown(Server var1);
/** @deprecated */
@Deprecated
List<Server> getServerList(boolean var1);
List<Server> getReachableServers();
List<Server> getAllServers();}
(2)IRule 是负载均衡策略的抽象,ILoadBalancer 通过调用 IRule 的 choose()方法返回 Server,其核心方法如下:
public interface IRule {Server choose(Object var1);
void setLoadBalancer(ILoadBalancer var1);
ILoadBalancer getLoadBalancer();}
IRule 的实现类有:
- BestAvailableRule 跳过熔断的 Server,在剩下的 Server 中选择并发请求最低的 Server
- ClientConfigEnabledRoundRobinRule 轮询
- RoundRobinRule 轮询
- RandomRule 随机选择
- RetryRule 可重试的策略,可以对其他策略进行重试,默认轮询重试
- WeightedResponseTimeRule 根据响应时间加权,响应时间越短权重越大
- AvailabilityFilteringRule 剔除因为连续链接、读失败或链接超过最大限制导致熔断的 Server,在剩下读 Server 中进行轮询
(3)IPing 用来检测 Server 是否可用,ILoadBalancer 的实现类维护一个 Timer 每隔 10s(this.pingIntervalSeconds = 10)检测一次 Server 的可用状态
public interface IPing {boolean isAlive(Server var1);
}
四、总结
- Ribbon 是 Spring Cloud 框架中比较核心的模块,负责着服务负载调用,Ribbon 可以脱离 SpringCloud 单独使用。
- Ribbon 是客户端的负载均衡框架,每个客户端上,独立维护着自身的调用信息统计,相互隔离,Ribbon 的负载均衡表现在各个机器上变现并不完全一致
- Ribbon 是整个组件框架中最复杂的一环,控制流程上为了保证服务的高可用性,有很多比较细节的参数控制