1.Ribbon概述
1.1.是什么
1.2.官网资料
https://github.com/Netflix/ribbon/wiki/Getting-StartedRibbon目前也进入维护模式
未来替换方案
1.3.能干嘛
1.3.1.LB(负载均衡)
集中式LB
进程内LB
一句话:负载均衡+RestTemplate调用
2.Ribbon负载均衡演示
2.1.架构说明
总结: Ribbon其实就是一个软负载均衡的客户端组件, 他可以和其他所需请求的客户端结合使用,和eureka结合只是其中一个实例.
2.2.POM
2.3.二说RestTemplate的使用
官网:
getForObject方法/getForEntity方法
postForObject/postEntity
GET请求方法
POST请求方法
3.Ribbon核心组件IRule
IRule:根据特定算法从服务列表中选取一个要访问的服务
说明:
RoundRobinRule: 默认轮询的方式
RandomRule: 随机方式
WeightedResponseTimeRule: 根据响应时间来分配权重的方式,响应的越快,分配的值越大。
BestAvailableRule: 选择并发量最小的方式
RetryRule: 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
ZoneAvoidanceRule: 根据性能和可用性来选择。
AvailabilityFilteringRule: 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)
4.修改Ribbon默认的负载均衡规则
方式一:修改代码更换负载均衡策略
第一步:新建一个不会被@ComponentScan组件扫描到的包,如:com.rules
第二步:在该包下新建自己的负载均衡算法的规则类
第三步:主启动类上添加注解:@RibbonClient
package com.rules;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @BelongsProject: MicroService
* @BelongsPackage: com.rules
* @CreateTime: 2020-11-18 16:50
* @Description: TODO
*/
public class MyLoadBalanceRule {
/**
* @desc 自定义负载均衡规则,默认是轮询规则
* @return
*/
public IRule myRule(){
//return new RandomRule(); // 改为随机算法规则
return new RoundRobinRule(); // 轮询
}
}
//开启客户端
(name = "PRODUCT-SERVICE",configuration = MyLoadBalanceRule.class)
public class ProtalApp80 {
public static void main(String[] args) {
SpringApplication.run(ProtalApp80.class,args);
}
}
方式二:修改配置文件更换负载均衡策略
第二种方式在application.properties中设置分配的策略
#设置负载均衡策略 eureka-ribbon-provider 为调用的服务的名称
eureka-ribbon-provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
'eureka-ribbon-provider’是调用的服务的名称,后面的组成部分是固定的。
同时注释掉方式一中的内容
5.Ribbon负载均衡算法
5.1.原理
5.2.源码跟踪
为什么我们只输入了service名称就可以访问了呢?之前还要获取ip和端口。显然有人帮我们根据service名称,获取到了服务实例的ip和端口。它就是LoadBalancerInterceptor
我们进行源码跟踪:
继续跟入execute方法:发现获取了8001端口的服务
org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient
如果再跟下一次,发现获取的是8002
5.3.负载均衡策略
Ribbon默认的负载均衡策略是简单的轮询,我们可以测试一下:
编写测试类,在刚才的源码中我们看到拦截中是使用RibbonLoadBalanceClient
来进行负载均衡的,其中有一个choose
方法,是这样介绍的:
现在这个就是负载均衡获取实例的方法。我们对注入这个类的对象,然后对其测试:
package com.bruceliu.test;
import com.bruceliu.SpringcloudDemoConsumerApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author bruceliu
* @create 2019-05-04 11:33
* @description 负载均衡算法测试
*/
(SpringRunner.class)
(classes = SpringcloudDemoConsumerApplication.class)
public class LoadBalanceTest {
RibbonLoadBalancerClient client;
public void test1(){
for (int i = 0; i <10 ; i++) {
ServiceInstance instance = this.client.choose("SPRINGCLOUD-DEMO-SERVICE");
System.out.println(instance.getHost() + ":" + instance.getPort());
}
}
}
运行结果:
符合了我们的预期推测,确实是轮询方式。
我们是否可以修改负载均衡的策略呢?继续跟踪源码,发现这么一段代码:
我们看看这个rule是谁:
这里的rule默认值是一个RoundRobinRule
,看类的介绍:
这不就是轮询的意思嘛。
我们注意到,这个类其实是实现了接口IRule的,查看一下:
定义负载均衡的规则接口。
它有以下实现:
SpringBoot也帮我们提供了修改负载均衡规则的配置入口:
SPRINGCLOUD-DEMO-SERVICE
ribbon
NFLoadBalancerRuleClassName com.netflix.loadbalancer.RandomRule
格式是:{服务名称}.ribbon.NFLoadBalancerRuleClassName
,值就是IRule的实现类。
再次测试,发现结果变成了随机: