Ribbon
基于HTTP和TCP的客户端负载均衡工具,主要负责请求分发,服务之间通讯基于Http Restful。SpringCloud服务调用方式有Rribbon+RestTemplate和Feign。当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,选择其中一个服务提供者实例,Ribbon提供了一套微服务负载均衡解决方案
负载均衡(LB):将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用),常见nginx,lvs,硬件F5
- 集中式:在服务的消费方和提供方之间是有独立的LB设施,可以是硬件如F5,软件如Nginx,由该设施负责把访问请求通过某种策略转发至服务的提供方。如nginx是服务器负载均衡,客户端所有请求都会交给nginx,由nginx实现请求转发,即由服务端实现负载均衡。
- 进程内:LB逻辑集成到消费方,消费方从服务注册中心获知可用服务地址,然后自己从中选择一个合适的服务器发起请求。如ribbon是客户端负载均衡,在调用微服务接口时,会从注册中心获取注册信息服务列表后缓存到jvm本地,从而在本地实现rpc远程调用技术
调用方式:
- 启动类声明RestTemplate的bean,用@LoadBalanced注解修饰
- http调用时,采用@Autowired注入RestTemplate,通过RestTemplate写服务名进行调用,有以下两个方法调用:getForEntity:获取更详细的信息 getForObject:只返回结果json串
负载均衡策略IRule路由:
IRule接口代表负载均衡策略,通过特定算法选取要访问的服务,常使用结合可
- RoundRobinRule:系统内置的默认负载均衡规范,轮询,第N次请求 % 服务器集群总数 = 实际调用服务器位置下标。通过CAS保证多次请求不会拿到相同的N。
- RandomRule:随机,在存活的服务列表中随机选择一个服务下标,随机找一个服务器,尽量将流量分散在各个服务器上
- RetryRule:先按轮询策略获取服务,如果获取失败则在指定时间内进行重试,获取可用服务
- WeightedResponseTimeRule:对轮询的扩展,响应速度越快的实例选择权重越大,越容易被选择
- BestAvailableRule:先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务。忽略那些请求失败的服务器,然后尽量找并发比较低的服务器来请求
- AvailabilityFilteringRule:过滤掉由于多次访问故障而处于断路器状态的服务,还有并发请求数超过阈值的服务,对剩余的服务列表进行轮询。如果3次连接失败,就会等待30秒后再次访问;如果不断失败,那么等待时间会不断变长。如果某个服务器的并发请求太高了,那么会绕过去,不再访问
- ZoneAvoidanceRule:复合判断server所在区域的性能和server的可用性选择服务器,然后利用AvailabilityFilteringRule过滤,就是机房。
自定义负载均衡策略:
1、创建自定义策略配置类,不能在@ComponentScan配置扫描包路径下,配置添加@Configuration注解,创建一个新的IRule的Bean,创建自定义策略
2、在客户端启动类添加@RibbonClient注解,定义需要采用自定义注解访问的服务和自定义策略类
轮询算法原理:rest接口的第n次请求 % 服务器集群总数量 = 实际调用服务器位置下标,每次服务重启后rest接口计数从1开始。通过从服务名获取实例list,通过index去轮询访问服务
Ribbon原理图:

Ribbon原理:
首先获取所有标识@LoadBalanced注解的RestTemplate,然后将Ribbon默认的拦截器LoadBalancerInterceptor添加到RestTemplate中,这样当使用http请求时就会起到拦截的作用。当有请求发起时,拦截器会创建ILoadBalancer(里面包含了选取服务的规则(IRule)、服务集群的列表(ServerList)、检验服务是否存活(IPing)等特性)。然后从服务集群中选择一个服务,最后向这个服务发送请求。
IPing:
保证服务可用的基石,算法如下:可以设置默认返回true,永久返回true、用HttpClient对服务发起ping检测、不使用ping,通过client的反馈判断
- NIWSDiscoveryPing:不执行Ping操作,将每个server list中的server,都检查一下server对应的一个eureka中的instanceInfo额状态,看看服务实例的status是否正常。
- PingUrl:使用HttpClient对服务进行Ping操作
- DummyPing:默认返回true,默认的ping。ribbon跟eureka整合后,使用的是eureka的IPing组件,不是ribbon的
- NoOpPing:永远返回true
IPing组件默认不生效,eureka有自己的故障发现和服务实例摘除机制,不需要ribbon自己去判断server是否存活。
在ZoneAwareLoadBalancer实例构造时,会启动一个定时调度任务。每隔30S,就用IPing组件对server list中的每个server都执行以下isAlive方法,判断server是否存活。
Ribbon跟Nginx的区别:Nginx属于服务端的负载均衡,客户端发起请求不知道会被负载到哪台机器上,Ribbon属于客户端的负载均衡,发起的请求都是明确的。
默认的负载均衡策略可能存在的问题:
如果server宕机下线了,但是由于注册表的刷新是30s一次,并且在eureka中下线过程也是有一定时间的。在这个时间段内,可能实例已经宕机,但是轮询请求还是会不断把请求发送到宕机的服务上去,造成请求多次失败。在springCloud中,这类问题可以采用hystrix做资源隔离,熔断和降级,对这个请求失败的服务实例,就走降级机制。
本文来自博客园,作者:难得,转载请注明原文链接:https://www.cnblogs.com/zhangbLearn/p/18829362

浙公网安备 33010602011771号