SpringCloud入门—RIbbon负载均衡
一、介绍
- 背景
当系统面临大量的用户访问,负载过高的时候,通常会增加服务器数量来进行横向扩展(集群),多个服务器的负载需要均衡,以免出现服务器负载不均衡,部分服务器负载较大,部分服务器负载较小的情况。通过负载均衡,使得集群中服务器的负载保持在稳定高效的状态,从而提高整个系统的处理能力。
二、两种负载均衡
软件负载均衡分为:服务端(集中式),客户端。
服务端负载均衡:在客户端和服务端中间使用代理,nginx。
客户端负载均衡:根据自己的情况做负载。Ribbon就是。
客户端负载均衡和服务端负载均衡最大的区别在于 服务端地址列表的存储位置,以及负载算法在哪里。
客户端负载均衡
在客户端负载均衡中,所有的客户端节点都有一份自己要访问的服务端地址列表,这些列表统统都是从服务注册中心获取的;
服务端负载均衡
在服务端负载均衡中,客户端节点只知道单一服务代理的地址,服务代理则知道所有服务端的地址。
Ribbon使用的是客户端负载均衡。
而在Spring Cloud中我们如果想要使用客户端负载均衡,方法很简单,使用@LoadBalanced注解即可,这样客户端在发起请求的时候会根据负载均衡策略从服务端列表中选择一个服务端,向该服务端发起网络请求,从而实现负载均衡。
上面几种负载均衡,硬件,软件(服务端nginx,客户端ribbon)。目的:将请求分发到其他功能相同的服务。
手动实现,其实也是它的原理,做事的方法。
手写客户端负载均衡
1、知道自己的请求目的地(虚拟主机名,默认是spring.application.name)
2、获取所有服务端地址列表(也就是注册表)。
3、选出一个地址,找到虚拟主机名对应的ip、port(将虚拟主机名 对应到 ip和port上)。
4、发起实际请求(最朴素的请求)。
三、Ribbon实例
Ribbon完成客户端的负载均衡,过滤掉DOWN的服务。
MainController.class
package com.zhow.eurekaconsumer;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@RestController
public class MainController {
//Ribbon负载均衡实例类
@Resource
private LoadBalancerClient loadBalancerClient;
@GetMapping("client4")
public String client4() {
//通过Ribbon选择 不用手动获取服务列表去选择
//Ribbon 已经完成一遍过滤把DOWN的服务剔除出去
ServiceInstance instanceInfo = loadBalancerClient.choose("Eureka-provider");
//拼接调用url http://192.168.14.81:8080/hi
String url = "http://" + instanceInfo.getHost() + ":" + instanceInfo.getPort() + "/hi";
System.out.println(url);
//使用RestTemplate 调用实例方法
RestTemplate restTemplate = new RestTemplate();
String respStr = restTemplate.getForObject(url, String.class);
//返回值:hello world
System.out.println(respStr);
return respStr;
}
}
四、负载均衡算法
默认实现:
ZoneAvoidanceRule(区域权衡策略):复合判断Server所在区域的性能和Server的可用性,轮询选择服务器。
其他规则:
BestAvailableRule(最低并发策略):会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务。逐个找服务,如果断路器打开,则忽略。
RoundRobinRule(轮询策略):以简单轮询选择一个服务器。按顺序循环选择一个server。
RandomRule(随机策略):随机选择一个服务器。
AvailabilityFilteringRule(可用过滤策略):会先过滤掉多次访问故障而处于断路器跳闸状态的服务和过滤并发的连接数量超过阀值得服务,然后对剩余的服务列表安装轮询策略进行访问。
WeightedResponseTimeRule(响应时间加权策略):据平均响应时间计算所有的服务的权重,响应时间越快服务权重越大,容易被选中的概率就越高。刚启动时,如果统计信息不中,则使用RoundRobinRule(轮询)策略,等统计的信息足够了会自动的切换到WeightedResponseTimeRule。响应时间长,权重低,被选择的概率低。反之,同样道理。此策略综合了各种因素(网络,磁盘,IO等),这些因素直接影响响应时间。
RetryRule(重试策略):先按照RoundRobinRule(轮询)的策略获取服务,如果获取的服务失败则在指定的时间会进行重试,进行获取可用的服务。如多次获取某个服务失败,就不会再次获取该服务。主要是在一个时间段内,如果选择一个服务不成功,就继续找可用的服务,直到超时。
五、切换负载均衡策略
注解方式
@Bean
public IRule myRule(){
//return new RoundRobinRule();
return new RandomRule();
}
配置文件
针对服务定ribbon策略:
Eureka-provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
注解方法优先级高于配置文件。