负载均衡
将请求流量分发到不同的服务器就是所谓的负载均衡,目前市面上主要有以F5为代表的硬件负载,和以ngnix、HA Proxy为代表的软件负载。
负载均衡所处位置可以分为
- 服务端负载,即对客户端而言是完全透明的,客户端并不知道具体的负载策略
- 客户端负载,即客户端已知可用的服务器列表,根据策略来选择可用的服务端
无论是在客户端还是服务端去做负载均衡,负载均衡都需要通过心跳机制看来知道哪些服务器是可用的,并从这些可用的服务器中,根据均衡策略来选择一台处理客户端的请求。
Spring Cloud Netflix Ribbon
Spring Cloud Netflix Ribbon是Netflix发布的开源项目,在客户端实现负载均衡。以下内容来自Spring Cloud中服务的发现与消费。
Ribbon 是一个基于HTTP和TCP的客户端负载均衡器,当我们将Ribbon和Eureka一起使用时,Ribbon会从Eureka注册中心去获取服务端列表,然后进行轮询访问以到达负载均衡的作用,客户端负载均衡中也需要心跳机制去维护服务端清单的有效性,当然这个过程需要配合服务注册中心一起完成。
特点
- 和Eureka完美整合
- 支持多种协议-HTTP,TCP,UDP
- caching/batching
- built in failure resiliency
主要组件
- ServerList,负载均衡使用的服务器列表。这个列表会缓存在负载均衡器中,并定期更新。当Ribbon与Eureka结合使用时,ServerList的实现类就是DiscoveryEnabledNIWSServerList,它会保存Eureka Server中注册的服务实例表。
- ServerListFilter,服务器列表过滤器。这是一个接口,主要用于对Service Consumer获取到的服务器列表进行预过滤,过滤的结果也是ServerList。Ribbon提供了多种过滤器的实现。
- IPing,探测服务实例是否存活的策略。
- IRule,负载均衡策略,其实现类表述的策略包括:轮询、随机、根据响应时间加权等。我们也可以自己定义负载均衡策略,比如我们就利用自己实现的策略,实现了服务的版本控制和直连配置。实现好之后,将实现类重新注入到Ribbon中即可。
- ILoadBalancer,负载均衡器。这也是一个接口,Ribbon为其提供了多个实现,比如ZoneAwareLoadBalancer。而上层代码通过调用其API进行服务调用的负载均衡选择。一般ILoadBalancer的实现类中会引用一个IRule。
- RestClient,服务调用器。顾名思义,这就是负载均衡后,Ribbon向Service Provider发起REST请求的工具。
负载均衡策略
- 简单轮询负载均衡(RoundRobin)以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。
- 随机负载均衡 (Random),随机选择状态为UP的Server。
- 加权响应时间负载均衡 (WeightedResponseTime),根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。
- 区域感知轮询负载均衡(ZoneAvoidanceRule),复合判断server所在区域的性能和server的可用性选择server。
与Eureka合作时的工作流程
- 优先选择在同一个Zone且负载较少的Eureka Server。
- 定期从Eureka更新并过滤服务实例列表。
- 根据用户指定的策略,在从Server取到的服务注册列表中选择一个实例的地址。
- 通过RestClient进行服务调用。
到此,以上是对Ribbon的简单介绍。
参考文献:
https://segmentfault.com/a/1190000006162832