1.基本概念
SpringCloud Ribbon是基于Netflix Ribbon 实现的一套客户端负载均衡的工具。简单的说,Ribbon 是 Netflix 发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将 Netflix 的中间层服务连接在一 起。Ribbon 的客户端组件提供一系列完整的配置项,如:连接超时、重试等。简单的说,就是在配置文 件中列出 LoadBalancer (简称LB:负载均衡) ,Ribbon 会自动的帮助你基于某种规则 (如简单轮询,随机 连接等等) 去连接这些机器。我们也容易使用 Ribbon 实现自定义的负载均衡算法!
Ribbon组件就像是服务提供方和服务消费方之间的一个中间层,将用户的请求合理的分配给服务方。
LB,即负载均衡,在微服务或分布式集群中经常用的一种应用。负载均衡简单的说就是 将用户的请求平摊的分配到多个服务上,从而达到系统的HA (高用)。常见的负载均衡软件有 Nginx、Lvs 等等。Dubbo、SpringCloud 中均给我们提供了负载均衡,SpringCloud 的负载均衡算法可以自定义。 负载均衡简单分类:
集中式LB
即在服务的提供方和消费方之间使用独立的LB设施,如Nginx(反向代理服务器),由该设施负责把访问 请求通过某种策略转发至服务的提供方!
进程式 LB
将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一 个合适的服务器。Ribbon 就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获 取到服务提供方的地址!
2.Ribbon组件的使用
第一步:引入依赖
其实ribbon依赖并不需要单独引入,spring-cloud-starter-netflix-eureka-client这个依赖已经集成了ribbon
第二步:在服务消费方开启负载均衡
在RestTemplate组件上,使用@LoadBalanced注解开启负载均衡的调用
@Bean
@LoadBalanced//开启负载均衡的访问
public RestTemplate restTemlate(){return new RestTemplate();
}
第三步:使用服务提供方的名称进行服务调用
@RestController@RequestMapping("consumer")@SuppressWarnings("all")public class PaymentController {@AutowiredRestTemplate restTemplate;
//通过服务实例名称进行访问
}@RequestMapping("findById/{id}")public Result<Payment> findById(@PathVariable("id") Long id){String url = "http://SERVICE-PROVIDER/provider/findById?id=" + id;Result result = restTemplate.getForObject(url, Result.class);return result;}
3.Ribbon负载均衡的算法策略
Ribbon负载均衡有一个接口:IRule。这个接口定义了负载均衡的相关约束和规范
public interface IRule {Server choose(Object var1);void setLoadBalancer(ILoadBalancer var1);ILoadBalancer getLoadBalancer();
}
这个接口有很多实现类,不同的实现类就是不同的负载均衡算法策略
下面分别介绍这些策略
(1)轮询策略
轮询策略:RoundRobinRue,按照一定的顺序依次调用服务实例。比如一共有 3 个服务,第一次调用 服务 1,第二次调用服务 2,第三次调用服务3,依次类推。此策略的yml配置设置如下:
service-provider: # 服务提供方的名称ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #设置负载均衡
(2)权重策略
权重策略:WeightedResponseTimeRule,根据每个服务提供者的响应时间分配一个权重,响应时间 越长,权重越小,被选中的可能性也就越低。它的实现原理是,刚开始使用轮询策略并开启一个计时 器,每一段时间收集一次所有服务提供者的平均响应时间,然后再给每个服务提供者附上一个权重,权 重越高被选中的概率也越大。此策略的配置设置如下:
service-provider: # 服务提供方的名称ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
(3)随机策略
随机策略:RandomRule,从服务提供者的列表中随机选择一个服务实例。此策略的配置设置如下:
service-provider: # 服务提供方的名称ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #设置随机策略的负载均衡
(4)最小连接数策略
最小连接数策略:BestAvailableRule,也叫最小并发数策略,它是遍历服务提供者列表,选取连接数 最小的⼀个服务实例。如果有相同的最小连接数,那么会调用轮询策略进行选取。此策略的配置设置如 下:
service-provider: # 服务提供方的名称ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule #设置负载均衡
(5)重试策略
重试策略:RetryRule,按照轮询策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定 的时间之内不断地进行重试来获取服务,如果超过指定时间依然没获取到服务实例则返回 null。此策略 的配置设置如下:
ribbon:ConnectTimeout: 2000 # 请求连接的超时时间ReadTimeout: 5000 # 请求处理的超时时间 service-provider: # 服务提供方的名称ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule #设置负载均衡
(6)可用敏感性策略
可用敏感性策略:AvailabilityFilteringRule,先过滤掉非健康的服务实例(指那些处于不正常运行状态,无法正常处理客户端请求的实例),然后再选择连接数较小的服 务实例。此策略的配置设置如下:
service-provider: # 服务提供方的名称ribbon:NFLoadBalancerRuleClassName:com.netflix.loadbalancer.AvailabilityFilteringRule
(7)区域敏感性策略
区域敏感策略:ZoneAvoidanceRule,根据服务所在区域(zone)的性能和服务的可用性来选择服务 实例,在没有区域的环境下,该策略和轮询策略类似。此策略的配置设置如下
service-provider: # 服务提供方的名称ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.ZoneAvoidanceRule
下面来讲一下轮询负载均衡算法原理
负载均衡轮询算法: rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标 ,每次服务 重启动后rest接口计数从1开始。
如:
List[0] instances = 127.0.0.1:8002
List[1] instances = 127.0.0.1:8001
8001 + 8002 组合成为集群,它们共计2台机器,集群总数为2,按照轮询算法原理:
当总请求数为1时: 1 % 2 = 1对应下标位置为1,则获得服务地址为127.0.0.1:8001
当总请求数位2时: 2 % 2 = 0对应下标位置为0,则获得服务地址为127.0.0.1:8002
当总请求数位3时: 3 % 2 = 1对应下标位置为1,则获得服务地址为127.0.0.1:8001
当总请求数位4时: 4 % 2 = 0对应下标位置为0,则获得服务地址为127.0.0.1:8002
如此类推……