负载均衡
什么是负载均衡?
ribbon是基于netflix ribbon实现的一个工作在consumer端的负载均衡工具,提供了很多负载均衡策略:轮询、随机
通俗的讲,负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上进行执行。
为什么要用负载均衡(ribbon)?
在使用nacos时,我们是使用服务名以及索引(get(0))获取服务,在搭建集群后,我们想让请求分散到不同的服务器上,但是通过索引(get(0)),获取的服务并不是负载均衡,搭建的集群也是毫无意义的,所以我们就要使用ribbon即负载均衡,将请求分散到不同的服务器中。
自定义负载均衡
使用随机数
在消费层使用随机数工具,随机获取服务索引
@RequestMapping(value="/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
//获取随机数
int currentIndex = new Random().nextInt(2);
//通过随机数,获取nacos中注册的指定服务信息
ServiceInstance instance = discoveryClient.getInstances("ribbon-provider").get(currentIndex);
//拼接服务路径
String url = "http://"+instance.getHost()+":"+instance.getPort()+"/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
轮播方式
任何数(a)除以任意数(b)的余数范围是:[0—(a-1)],由此我们可以统过求余数使请求有序的轮播到每个服务上
注:声明成员变量的原因是,如果是局部变量,每次执行此方法时,变量都会重新赋值,这样求余的数都是一样的,就导致访问的服务总是是同一个,无法起到轮播效果,搭建的集群也失去意义
//声明成员变量
private int index;
@RequestMapping(value="/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
//获取所有服务
List<String> serviceList = discoveryClient.getServices();
//每执行一次变量自加1
index = index+1;
//通过求余数,获取服务索引
int currentIndex = (index)%serviceList.size();
//获取nacos中注册的指定服务信息
ServiceInstance instance = discoveryClient.getInstances("ribbon-provider").get(currentIndex);
//拼接服务路径
String url = "http://"+instance.getHost()+":"+instance.getPort()+"/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
使用ribbon
思考
以上自定义的两种方法都可以实现负载均衡,那我们为什么还要使用ribbon呢?
**答:**一个项目中,会有很多不同请求,如果全部都自定义,那么代码会冗余(重复代码过多),所有我们就要将这些代码封装起来,而这些已经有人为我们做好了,我们只需要使用就行了,ribbon就是其中一个
ribbon是什么?
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
我们不需要去引入ribbon的依赖,因为在nacos里面已经集成了ribbon的依赖
使用
首先修改配置类
在配置类上使用@LoadBalanced注解
添加了@LoadBalanced注解之后,Ribbon会给restTemplate请求添加一个拦截器,在拦截器中获取注册中心的所有可用服务,通过获取到的服务信息(ip,port)替换 serviceId 实现负载请求。
@Configuration
public class ConfigBean {
/**
* 发送rest请求的工具类
* @return
*/
@Bean
@LoadBalanced //开启ribbon负载均衡,默认使用轮询策略
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
轮播方式
ribbon默认使用轮播的方式处理请求,由于ribbon会,通过获取到的服务信息(ip,port)替换 serviceId 实现负载请求,所以我们需要写出服务名即可,ribbon会自动为我们替换
url = “http://” + 服务名+ 请求路径
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
String url = "http://ribbon-provider/provider/getUserById/"+id;
return restTemplate.getForObject(url,User.class);
}
随机方式
只需要往IOC容器中添加一个Bean,即可实现随机
//在nacos配置类中添加
@Bean
public IRule iRule(){
return new RandomRule();
}