概述
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套。客户端负载均衡的工具。
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项,如连接超时,重试。简单的说,就是在配置文件中列出Load Balancer (简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮洵,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。
官网资料 https://github.com/Netflix/ribbon/wiki/Getting-Started
Ribbon目前也进入维护模式
未来替换方案 SpringCloud loadBalancer
作用
集中式LB
进程内LB
Ribbon负载均衡演示
架构说明
总结: Ribbon其实就是一个软负载均衡的客户端组件, 他可以和其他所需请求的客户端结合使用,和eureka结合只是其中一个实例.
pom
RestTemplate的使用
getForObject方法/getForEntity方法
返回对象为响应体中数据 转换成的对象,基本上可以理解为json
返回对象为ResponseEntity对象,包含了响应中的一些重要信息,比如响应头,响应状态码,响应体等
其他类型方法 同上
Ribbon核心组件IRule
IRule:根据特定算法从服务列表中选取一个要访问的服务
com.netflix.loadbalancer.RoundRobinRule | 轮询 |
---|---|
com.netflix.loadbalancer.RandomRule | 随机 |
com.netflix.loadbalancer.RetryRule | 先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内进行重试,获取可用的服务 |
WeightedResponseTimeRule | 对RoundRobinRule的扩展,响应速度越快的实例选择权重越多大,越容易被选择 |
BestAvailableRule | 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务 |
AvailabilityFilteringRule | 先过滤掉故障实例,再选择并发较小的实例 |
ZoneAvoidanceRule | 默认规则,复合判断server所在区域的性能和server的可用性选择服务器 |
如何替换
- 修改cloud-consumer-order80
- 注意配置细节
- 新建package
com.carve.myrule
并创建类MySelfRule
- 在启动类OrderMain80上添加
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MySelfRule.class)
- 测试
http://localhost/consumer/payment/get/31
Ribbon负载均衡算法
原理
手写
启动7001/7002
修改8001/8002 Controller并启动
@GetMapping(value = "/payment/lb")
public String getPaymentLB() {
return serverPort;
}
Bean配置类中去掉注解@LoadBalanced
自定义接口
public interface LoadBalancer {
ServiceInstance instances(List<ServiceInstance> serviceInstance);
}
@Component
public class LoadBalancerImpl implements LoadBalancer {
@Autowired
private DiscoveryClient discoveryClient;
private AtomicInteger atomicInteger = new AtomicInteger(0);
public final int getAndIncrement() {
int current;
int next;
do {
current = this.atomicInteger.get();
next = current >= 2147483647 ? 0 : current + 1;
} while (!this.atomicInteger.compareAndSet(current, next));
System.err.println("****** next: " + next);
return next;
}
// 负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标 , 每次服务重启动后rest 接口计数从1开始
@Override
public ServiceInstance instances(List<ServiceInstance> instances) {
int index = getAndIncrement() % instances.size();
return instances.get(index);
}
}
启动类
Controller
@Autowired
private LoadBalancer loadBalancer;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping(value = "/consumer/payment/lb")
public String getPaymentLB() {
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
if (CollectionUtils.isEmpty(instances)) {
return null;
}
ServiceInstance serviceInstance = loadBalancer.instances(instances);
URI uri = serviceInstance.getUri();
System.out.println(uri + "/payment/lb");
return restTemplate.getForObject(uri + "/payment/lb", String.class);
}