Ribbon是什么?

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

负载均衡

负载均衡(Load Balance),意思是将负载(工作任务,访问请求)进行平衡、分摊到多个操作单元(服务器,组件)上进行执行。是解决高性能,单点故障(高可用),扩展性(水平伸缩)的终极解决方案。

集中式LB和进程内LB

而负载均衡又分为两类,集中式负载均衡和进程内负载均衡,什么是集中式负载均衡和进程内负载均衡?

集中式负载均衡
在服务的消费方和提供方之间使用独立的负载均衡设施(可以是硬件,如F5,也可以是软件,如nginx),由该设施负责吧访问请求通过某中策略转发至服务的提供方

进程内负载均衡
将负载均衡逻辑集成到消费方,消费方从服务注册中心获知那些地址可用,然后自己再从这些地址中选择一个合适的服务器,例如ribbon,ribbon只是一个类库,集成在消费方进程,消费方通过它来获取到服务提供方的地址

Riboon怎么做到负载均衡的?

先看看Ribbon的原理图
从下面的原理图可以看到服务提供者去注册服务到注册中心Eureka去,而服务消费者通过Ribbon去服务注册中心获取查询这些可以的服务列表,然后根据要调用的那个服务进行负载均衡请求

Ribbon自带的负载均衡算法


Ribbon自带了7中负载均衡算法

1、RoundRobinRule
默认的,轮询规则,也是很多高级规则中退避的一种策略

2、 AvailabilityFilteringRule
会过滤掉打开熔断的服务或者是高并发连接数量的服务

3、 WeightedResponseTimeRule
通过服务的平均响应时间,给每一个服务一个权重,响应时间越长,权重越小,开始统计信息不足,应用轮询策略

4、 RetryRule
先按照轮询策略,如果请求服务失败,会在指定时间内进行重试

5、 BestAvailableRule
先过滤掉断路器的服务,然后选择一个并发量最小的

6、 RandomRule
随机获取一个服务

7、ZoneAvoidanceRule
根据性能和可用性来选择。

Ribbon默认是使用轮询的算法,怎么修改?

第一步
添加自定义类,但是要注意存放的位置这个自定义的类不能放在@ComponentScan所扫描的当前包以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是我们达不到特殊化指定的目的了,也就是说不能放在与主启动类同包及子包下

第二步
在客户端添加一个controller,去调用服务

@GetMapping("/consumer/payment/get/{id}")public CommonResult<Payment> getPayment(@PathVariable("id")Long id){return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);}

第三步
将三个服务添加注册到服务中心

调用消费者模块的/consumer/payment/get/{id},成功出现随机的


如果我们想用自己写的负载均衡算法怎么办?

先看看ribbon的负载均衡算法是什么结构?怎么写的?

先看看这个接口,这个接口是Ribbon中自己的负载均衡算法所实现的

看一下他的实现类,这个抽象类实现了IRule,抽象类实现接口是为了让子类更容易的去实现这个接口,这个抽象类只对IRule接口中的setLoadBalancer和getLoadBalancer进行了实现,把获取到的值进行赋值保存,方便的子类的使用,这两个方法可以看作是获取服务中心的服务信息

再来看看Ribbon的自己的负载均衡算法是怎么实现的?他实现了上面说的那个抽象类

首先会先调用这个choose,这个choose调用了父类AbstractLoadBalancerRule的getLoadBalancer,上面说过这个可以看作是获取服务中心的服务信息,然后调用了choose的重载方法

使用lb去获取存活(活跃)的服务和获取所有服务

获取服务数量的长度,然后调用chooseRandomInt(),去获取一个服务数量内的随机的下标,然后调用存放存活的服务的list通过下标去获取一个存活的服务

然后对获取的这个服务判断是否是存活状态,如果是存活状态就返回这个服务给调用者调用,如果不是存活的话 就就执行Thread.yield()线程让步,然后等再次循环拿下一个服务

Thread.yield( )解释

Java线程中的Thread.yield( )方法,译为线程让步。顾名思义,就是说当一个线程使用了这个方法之后,它就会把自己CPU执行的时间让掉,
让自己或者其它的线程运行,注意是让自己或者其他线程运行,并不是单纯的让给其他线程。
​ yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保
证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!

开始自定义负载均衡

从上面的源码分析可以看到我们要自定义负载均衡算法需要继承IRule的抽象实现类AbstractLoadBalancerRule,所以我们也可以写一个类去实现他,然后在 Server choose(ILoadBalancer lb, Object key) 里面设置规则

我们就先自定义一个轮询的,不使用ribbon自带的

编写一个类继承AbstractLoadBalancerRule,然后模仿ribbon自带的,创建一个choose的重载方法,注意:记得加上**@Component**注解,否则SpringBoot不会扫描到

@Component
public class MyRoundRobinRule extends AbstractLoadBalancerRule {//定义一个原子类,以保证原子性private AtomicInteger atomicInteger =new AtomicInteger(0);@Overridepublic void initWithNiwsConfig(IClientConfig iClientConfig) {}public Server choose(ILoadBalancer lb, Object key) {if (lb == null){return null;}//用于统计获取次数,当达到一定数量就不再去尝试int count = 0;Server server = null;//当服务还没获取到,并且尝试没有超过8次while (server == null && count++ < 8){//获取服务List<Server> allServers = lb.getAllServers();List<Server> reachableServers = lb.getReachableServers();int allServersSize = allServers.size();int reachableServersSize = reachableServers.size();//如果获取的服务list都为0就返回nullif(allServersSize == 0 || reachableServersSize == 0){return  null;}//获取服务下标int next = getServerIndex(allServersSize);//获取服务server = reachableServers.get(next);//如果服务为空直接跳过下面的if (server == null){continue;}//如果获取到的这个服务是活着的就返回if (server.isAlive()){return server;}//如果获取到的服务不是空,但是不是存活状态,需要重新获取server=null;}//最后这里可能会返回nullreturn  server;}//获取服务下标,为了保证原子性,使用了CASpublic int getServerIndex(int allServersSize){//自旋锁for (;;) {//获取当前值int current = this.atomicInteger.get();//设置期望值int next = (current + 1) % allServersSize;//调用Native方法compareAndSet,执行CAS操作if (this.atomicInteger.compareAndSet(current, next))//成功后才会返回期望值,否则无线循环return next;}}@Overridepublic Server choose(Object key) {return choose(getLoadBalancer(),key);}
}

在主启动类上添加
@RibbonClient(name = “CLOUD-PAYMENT-SERVICE” ,configuration = MyRoundRobinRule.class)
configuration 指定自己的负载均衡策略

在RestTemplate加@LoadBalanced

启动测试,成功出现轮询!


Ribbon自定义负载均衡算法相关推荐

  1. SpringCloud的Ribbon自定义负载均衡算法

    1.Ribbon默认使用RoundRobinRule策略轮询选择server 策略名 策略声明 策略描述 实现说明 BestAvailableRule public class BestAvailab ...

  2. Spring Cloud Alibaba - 11 Ribbon 自定义负载均衡策略(同集群优先权重负载均衡算法)

    文章目录 Pre 需求 工程 Code 继承AbstractLoadBalancerRule实现自定义Rule 随机权重策略 配置 验证 源码 Pre Spring Cloud Alibaba - 0 ...

  3. Spring Cloud Alibaba - 10 Ribbon 自定义负载均衡策略(权重算法)

    文章目录 Pre 工程 首先屏蔽细粒度配置 然后通过代码设置一个全局配置 指定 GlobalRibbonConfig GlobalRibbonConfig 设置负载均衡策略 开发自定义策略 (权重访问 ...

  4. Spring Cloud Alibaba - 06 RestTemplate 实现自定义负载均衡算法

    文章目录 负载均衡分类 分析 工程 调用 测试 源码 负载均衡分类 服务端负载均衡 ,比如我们常见的ng 客户端负载均衡 ,比如微服务体系中的ribbon spring cloud ribbon是 基 ...

  5. Ribbon默认负载均衡算法之轮训算法原理解析

    目录 此项目中用到的数据库脚本文件 父模块`cloud2020`中仅有一个`pom.xml`文件 项目结构图 `pom.xml`文件 1.创建一个微服务项目用来测试 1.1创建`cloud-api-c ...

  6. Ribbon 自定义负载均衡策略

    Ribbon默认的负载均衡策略默认的有下面几种: 我们也可以自定义负载均衡策略: 修改springcloud-consumer-dept-80的主启动类: 下面开始编写自定义配置类MySelfRule ...

  7. Spring Cloud Alibaba gateway ribbon 自定义负载均衡规则。发散灰度发布,金丝雀测试等

    上一篇介绍了,ribbon的组件.本篇要自己写一个灰度方案.其实就是一个很简单的思维扩散. 需求 前端header请求携带version字段.路由服务根据version去需要对应版本的服务集合,进行或 ...

  8. 6.Springcloud的Ribbon的负载均衡算法解析及配置方式

    项目地址: github地址 配置方式 1.在restTemplate配置类里面添加一个bean,用于确认所属的负载均衡算法类类型,全部代码如下: package com.debuggg.cloud. ...

  9. Ribbon负载均衡 算法

    1.Ribbon 简介 Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为.为Ribbon配置服务提供者地址列表后,Ribbon就可基于某种负载均衡算法,自动地帮助 ...

最新文章

  1. 这篇论文,透露谷歌团队构想的“未来搜索”
  2. 倒计时1天!CTA核心技术及应用峰会报名通道即将关闭(附参会攻略)
  3. php 汉字的首字母
  4. 学习笔记之Iframe
  5. jAVA 得到Map价值
  6. 八句经典座右铭必有一句适合你
  7. 进程间通信--命名管道(fifo)
  8. 机器学习理论与实战(十五)概率图模型03
  9. 图的建立-邻接矩阵表示(C语言)
  10. 模板:min-max容斥离散随机变量的几何分布(洛谷P3175:[HAOI2015]按位或)
  11. linux 双网卡 debian,Linux服务器双网卡双IP和单网卡双IP配置方法(Debian/Ubuntu)
  12. Permutations
  13. Java中反射的理解
  14. Linux Cgroups详解(一)
  15. 蓝牙BLE芯片PHY6222之SPI驱动ST7789
  16. 外接键盘Win键不能的使用问题以及FN键的使用
  17. DP4301国产低功耗Sub 1G收发器芯片兼容433MHz替代CC1101
  18. 3DMAX,png库错误解决方法
  19. 音频播放器—打开音频设备(扬声器)
  20. GPIO与IOMUX

热门文章

  1. Social Distance
  2. Excel 关闭网格线
  3. ACM 深搜 SeedingTempter of the Bone
  4. 我就是我,这世上不一样的烟火
  5. 两块网卡同时上网,笔者教你Win7如何设置两块网卡同时连接不同的网络
  6. C# 多线程四:互斥量Mutex的简单理解与运用
  7. 一些基础提(选择题)
  8. 【tensorflow2.0】34.word2vec作业代码
  9. rm -rf 文件恢复(不要抱太大的希望)
  10. SDL使用SDL_ttf显示文字