什么是
Ribbon 企业网站定制开发是一个基于HTTP和TCP企业网站定制开发的客户端负载均衡工具,它是基于 Ribbon 实现的。它不像Spring Cloud 企业网站定制开发服务注册中心、配置中心、企业网站定制开发网关那样独立部署,企业网站定制开发但是它几乎存在于每个Spring Cloud 微服务中。包括Feign 企业网站定制开发提供的声明式服务调用也是基于Ribbon实现的。Ribbon企业网站定制开发默认提供了很多种负载均衡算法,例如:轮询、随机等。甚至可以自定义负载均衡算法。Ribbon提供了一整套微服务的负载均衡解决方案
注意:从Spring Cloud Netflix 3.0 开始,Eureka整合包中已经替换了原来的Ribbon包而是使用的 spring-cloud-starter-loadbalancer,先关的使用也发生了改变
负载均衡方案
目前主流的负载均衡方案可分为两类:
- 集中式负载均衡(服务器负载均衡),即在consumer和provider之间使用独立的负载均衡设施,可以是硬件或软件,由该设施负责把访问请求通过某种策略转发至provider
- 进程内负载均衡(客户端负载均衡),将负载均衡逻辑集成到consumer,consumer从服务注册中心获知哪些地址可用,然后自己再从这些地址中选择合适的provider。Ribbon属于后者,它只是一个类库,集成与consumer中,consumer通过它来获取provider地址
Ribbon 负载均衡策略
1. 轮询策略(默认)
策略对应类名:RoundRobinRule
实现原理:轮询策略表示每次都顺序取下一个provider,例如一共有5个provider,第一次取第一个,第二次取第二个,以此类推。
2. 权重轮询策略
策略对应类名:WeightedResponseTimeRule
实现原理:根据每个provider的响应时间分配一个权重,响应时间越长,权重越低,被选中的可能性越低。权重轮询策略一开始为轮询策略,并开启一个计时器,每30秒收集一次每个provider的平均响应时间,当信息足够时,给每个provider附上一个权重,并按权重随机选择provider,高权重的provider会被高概率选中
3. 随机策略
策略对应类名:****
实现原理:从provider列表中随机选择一个
4. 最少并发数策略
策略对应类名:BestAvailableRule
实现原理:选择正在请求中并发数最少的provider,除非这个provider在熔断中
5. 重试策略
策略对应类名:RetryRule
实现原理:轮询策略的增强版, 轮询策略在服务不可用时是不做处理的,但是重试策略在服务不可用时会重新尝试集群中其他的节点
6. 可用性敏感策略
策略对应类名:AvailabilityFilteringRule
实现原理:过滤性能差的provider,如一直处于连接失败的provider,高并发的provider
7. 区域敏感性策略
策略对应类名:ZoneAvoidanceRule
实现原理:以一个区域为单位考察可用性,对于不可用的区域整个丢弃,从剩下区域中选择可用的provider,如果这个IP区域内有一个或多个实例不可达或者响应慢,都会降低该区域内其他IP被选中的权重
注意:从 Spring Cloud Netflix 3.0 以后的版本开始,就已经没有ribbon的依赖,它的负载均衡是依靠的Spring Cloud的负载均衡策略,并且只有两种:轮询策略 和 随机策略,实现的是 ReactorServiceInstanceLoadBalancer 接口,有兴趣的可以去看看源码
Ribbon入门案例
使用Eureka进行演示,可以参考文章:进行搭建注册中心
本次使用Eureka搭建服务提供者集群,相关代码可在文末的gitee仓库中查看
新版的Eureka默认已经集成了Ribbon因此不用再额外导入jar包
服务消费者测试代码,其他代码可以参考文章:
@Service("consumerDemoService2")public class ConsumerDemoService2 implements IConsumerDemoService { // Ribbon负载均衡器 @Autowired private LoadBalancerClient client; @Override public List<DemoEntity> list() { StringBuffer sb = new StringBuffer(); // 根据服务名称获取服务实例 ServiceInstance instance = client.choose("eureka-provider-demo"); if (ObjectUtils.isEmpty(instance)) return null; // 根据服务实例信息拼接请求地址 sb.append("http://") .append(instance.getHost()) .append(":") .append(instance.getPort()) .append("/list"); // 打印测试 System.out.println(sb.toString()); // 发起http请求 ResponseEntity<List<DemoEntity>> response = new RestTemplate().exchange(sb.toString(), HttpMethod.GET, null, new ParameterizedTypeReference<List<DemoEntity>>() { }); return response.getBody(); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
接下来启动测试,给消费者发现请求,从打印的服务提供者地址来看,可以看出默认的是轮询策略
Ribbon 负载均衡策略设置
负载均衡策略默认是 RoundRobinLoadBalancer
public class LoadBalancerConfig { @Bean ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) { String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); return new RandomLoadBalancer(loadBalancerClientFactory .getLazyProvider(name, ServiceInstanceListSupplier.class), name); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
注意:这个类不能使用 @Configuration 注解,否则负载均衡器会失效并抛出空指针异常
源码地址: