概述

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套。客户端负载均衡的工具。
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项,如连接超时,重试。简单的说,就是在配置文件中列出Load Balancer (简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮洵,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。

官网资料 https://github.com/Netflix/ribbon/wiki/Getting-Started

Ribbon目前也进入维护模式
未来替换方案 SpringCloud loadBalancer
image.png

作用

LB(负载均衡)

集中式LB

image.png

进程内LB

image.png

Ribbon负载均衡演示

架构说明

image.png
image.png
总结: Ribbon其实就是一个软负载均衡客户端组件, 他可以和其他所需请求的客户端结合使用,和eureka结合只是其中一个实例.

pom

image.png
image.png

RestTemplate的使用

官网 https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html
image.png

getForObject方法/getForEntity方法
返回对象为响应体中数据 转换成的对象,基本上可以理解为json
image.png
返回对象为ResponseEntity对象,包含了响应中的一些重要信息,比如响应头,响应状态码,响应体等
image.png
其他类型方法 同上

Ribbon核心组件IRule

IRule:根据特定算法从服务列表中选取一个要访问的服务

image.png

com.netflix.loadbalancer.RoundRobinRule 轮询
com.netflix.loadbalancer.RandomRule 随机
com.netflix.loadbalancer.RetryRule 先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内进行重试,获取可用的服务
WeightedResponseTimeRule 对RoundRobinRule的扩展,响应速度越快的实例选择权重越多大,越容易被选择
BestAvailableRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
AvailabilityFilteringRule 先过滤掉故障实例,再选择并发较小的实例
ZoneAvoidanceRule 默认规则,复合判断server所在区域的性能和server的可用性选择服务器

如何替换

  1. 修改cloud-consumer-order80
  2. 注意配置细节

image.png
image.png
image.png

  1. 新建package com.carve.myrule 并创建类MySelfRule

image.pngimage.png

  1. 在启动类OrderMain80上添加

@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MySelfRule.class)

  1. 测试

http://localhost/consumer/payment/get/31

Ribbon负载均衡算法

原理

image.png

手写

启动7001/7002
修改8001/8002 Controller并启动

  1. @GetMapping(value = "/payment/lb")
  2. public String getPaymentLB() {
  3. return serverPort;
  4. }

改造80服务

Bean配置类中去掉注解@LoadBalanced

image.png

自定义接口

image.png

  1. public interface LoadBalancer {
  2. ServiceInstance instances(List<ServiceInstance> serviceInstance);
  3. }
  4. @Component
  5. public class LoadBalancerImpl implements LoadBalancer {
  6. @Autowired
  7. private DiscoveryClient discoveryClient;
  8. private AtomicInteger atomicInteger = new AtomicInteger(0);
  9. public final int getAndIncrement() {
  10. int current;
  11. int next;
  12. do {
  13. current = this.atomicInteger.get();
  14. next = current >= 2147483647 ? 0 : current + 1;
  15. } while (!this.atomicInteger.compareAndSet(current, next));
  16. System.err.println("****** next: " + next);
  17. return next;
  18. }
  19. // 负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标 , 每次服务重启动后rest 接口计数从1开始
  20. @Override
  21. public ServiceInstance instances(List<ServiceInstance> instances) {
  22. int index = getAndIncrement() % instances.size();
  23. return instances.get(index);
  24. }
  25. }

启动类

注释掉@RibbonClient
image.png

Controller

  1. @Autowired
  2. private LoadBalancer loadBalancer;
  3. @Autowired
  4. private DiscoveryClient discoveryClient;
  5. @GetMapping(value = "/consumer/payment/lb")
  6. public String getPaymentLB() {
  7. List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
  8. if (CollectionUtils.isEmpty(instances)) {
  9. return null;
  10. }
  11. ServiceInstance serviceInstance = loadBalancer.instances(instances);
  12. URI uri = serviceInstance.getUri();
  13. System.out.println(uri + "/payment/lb");
  14. return restTemplate.getForObject(uri + "/payment/lb", String.class);
  15. }

测试

http://localhost/consumer/payment/lb
image.png