微服务负载均衡器Ribbon学习笔记

news2024/9/21 0:44:29

目录

1.什么是Ribbon

1.1 客户端的负载均衡

1.2 服务端的负载均衡

1.3  常见负载均衡算法

2. Nacos使用Ribbon

 3. Ribbon负载均衡策略

4.修改默认负载均衡策略

方式1:通过自定义配置类来实现

方式2:通过修改配置文件实现(推荐)

5.自定义负载均衡策略

6. 饥饿加载


1.什么是Ribbon

目前主流的负载方案分为以下两种:
集中式负载均衡,在消费者和服务提供方中间使用独立的代理方式进行负载,有硬件的(比如 F5),也有软件的(比如 
Nginx)。
客户端根据自己的请求情况做负载均衡,Ribbon 就属于客户端自己做负载均衡。
Spring Cloud  Ribbon是基于Netflix Ribbon 实现的一套 客户端的负载均衡工具, Ribbon客户端组件提供一系列的完善的配置,如超
时,重试等。通过 Load Balancer 获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询,随机)去调用这些服务。Ribbon也
可以实现我们自己的负载均衡算法。

1.1 客户端的负载均衡

例如spring cloud中的ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这是 客户端负载均衡;即在客户端就进行负载均衡算法分配。

1.2 服务端的负载均衡

例如Nginx,通过Nginx进行负载均衡,先发送请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端再进 行负载均衡算法分配。

 

1.3  常见负载均衡算法

  • 随机,通过随机选择服务进行执行,一般这种方式使用较少;
  • 轮训,负载均衡默认实现方式,请求来之后排队处理;
  • 加权轮训,通过对服务器性能的分型,给高配置,低负载的服务器分配更高的权重,均衡各个服务器的压力;
  • 地址Hash,通过客户端请求的地址的HASH值取模映射进行服务器调度。  ip --->hash
  • 最小链接数,即使请求均衡了,压力不一定会均衡,最小连接数法就是根据服务器的情况,比如请求积压数等参数,将请求分 配到当前压力最小的服务器上。  最小活跃数

2. Nacos使用Ribbon

nacos-discovery依赖了ribbon,可以不用再引入ribbon依赖
 添加 @LoadBalanced 注解
 修改controller
    @Autowired
    RestTemplate restTemplate;


    @GetMapping("/pay")
    public String pay(){
        String msg = restTemplate.getForObject("http://stock-nacos/stock/reduct", String.class);
        return "success" + "  " + msg;
    }

 3. Ribbon负载均衡策略

 

IRule
这是所有负载均衡策略的父接口, 里边的核心方法就是 choose 方法,用来选择一个服务实例
AbstractLoadBalancerRule
AbstractLoadBalancerRule 是一个抽象类,里边主要定义了一个 ILoadBalancer ,这里定义它的目的主要是 辅助负责均衡策略选取合适的服务端实 例。
  • RandomRule
看名字就知道,这种负载均衡策略就是 随机选择一个服务实例 ,看源码我们知道,在 RandomRule 的无参构造方法中初始化了一个 Random 对象,
然后在它重写的 choose 方法又调用了 choose(ILoadBalancer lb, Object key) 这个重载的 choose 方法,在这个重载的 choose 方法中,每次利用
random 对象生成一个不大于服务实例总数的随机数,并将该数作为下标所以获取一个服务实例。
  • RoundRobinRule
RoundRobinRule 这种负载均衡策略叫做线性 轮询负载均衡策略 。这个类的 choose(ILoadBalancer lb, Object key) 函数整体逻辑是这样的:开启 一个计数器count ,在 while 循环中遍历服务清单,获取清单之前先通过 incrementAndGetModulo 方法获取一个下标,这个下标是一个不断自增长 的数先加1 然后和服务清单总数取模之后获取到的(所以这个下标从来不会越界),拿着下标再去服务清单列表中取服务,每次循环计数器都会加 1,如果连续 10 次都没有取到服务,则会报一个警告 No available alive servers after 10 tries from load balancer: XXXX
  • RetryRule(在轮询的基础上进行重试)
看名字就知道这种负载均衡策略带有 重试 功能。首先 RetryRule 中又定义了一个 subRule ,它的实现类是 RoundRobinRule ,然后在 RetryRule 的 choose(ILoadBalancer lb, Object key)方法中,每次还是采用 RoundRobinRule 中的 choose 规则来选择一个服务实例,如果选到的实例正常就返
回,如果选择的服务实例为 null 或者已经失效,则在失效时间 deadline 之前不断的进行重试(重试时获取服务的策略还是 RoundRobinRule 中定义的 策略),如果超过了deadline 还是没取到则会返回一个 null
  • WeightedResponseTimeRule权重 —nacos的NacosRule ,Nacos还扩展了一个自己的基于配置的权重扩展
WeightedResponseTimeRule RoundRobinRule 的一个子类,在 WeightedResponseTimeRule 中对 RoundRobinRule 的功能进行了扩展, WeightedResponseTimeRule中会根据每一个实例的运行情况来给计算出该实例的一个 权重 ,然后在挑选实例的时候则根据权重进行挑选,这样能
够实现更优的实例调用。 WeightedResponseTimeRule 中有一个名叫 DynamicServerWeightTask 的定时任务,默认情况下每隔 30 秒会计算一次各个服务实例的权重,权重的计算规则也很简单, 如果一个服务的平均响应时间越短则权重越大,那么该服务实例被选中执行任务的概率也就越大
  • ClientConfigEnabledRoundRobinRule
ClientConfigEnabledRoundRobinRule 选择策略的实现很简单,内部定义了 RoundRobinRule choose 方法还是采用了 RoundRobinRule 的 choose方法,所以它的选择策略 RoundRobinRule 的选择策略一致 ,不赘述。
  • BestAvailableRule
BestAvailableRule 继承自 ClientConfigEnabledRoundRobinRule ,它在 ClientConfigEnabledRoundRobinRule 的基础上主要增加了根据 loadBalancerStats中保存的服务实例的状态信息来 过滤掉失效的服务实例的功能,然后顺便找出并发请求最小的服务实例来使用。 然而 loadBalancerStats有可能为 null ,如果 loadBalancerStats null ,则 BestAvailableRule 将采用它的父类即 ClientConfigEnabledRoundRobinRule的服务选取策略(线性轮询)。
  • ZoneAvoidanceRule (默认规则,复合判断server所在区域的性能和server的可用性选择服务器。ZoneAvoidanceRulePredicateBasedRule的一个实现类,只不过这里多一个过滤条件,ZoneAvoidanceRule中的过滤条件是以 ZoneAvoidancePredicate为主过滤条件和以 AvailabilityPredicate为次过滤条件组成的一个叫做CompositePredicate的组合过滤条件,过滤成功之后,继续采用线性轮询 (RoundRobinRule)的方式从过滤结果中选择一个出来。
  • AvailabilityFilteringRule(先过滤掉故障实例,再选择并发较小的实例) 过滤掉一直连接失败的被标记为circuit tripped的后端Server,并过滤掉那些高并发的后端Server或者使用一个AvailabilityPredicate来 包含过滤server的逻辑,其实就是检查status里记录的各个Server的运行状态。

4.修改默认负载均衡策略

方式1:通过自定义配置类来实现

1)新建配置类:

package com.ribbon;

import com.alibaba.cloud.nacos.ribbon.NacosRule;
import com.netflix.loadbalancer.IRule;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @BelongsProject: SpringCloudAlibabaLearn
 * @BelongsPackage: com.ribbon
 * @Author: wang fei
 * @CreateTime: 2023-01-19  16:41
 * @Description: TODO
 * @Version: 1.0
 */
@Configuration
public class RibbonConfig {
    /**
     * @description: 全局配置 指定负载均衡策略
     * 注意:此处有坑。不能写在@SpringbootApplication注解的@CompentScan扫描得到的地方,否则自定义的配置类就会被所有的RibbonClients共享。不建议这么使用,推荐yml方式
     * 方法名一定和IRule接口中关于负载均衡策略的名称一致
     * @method: iRule
     * @author: wang fei
     * @date: 2023/1/19 16:43:00
     * @param: []
     * @return: com.netflix.loadbalancer.IRule
    **/
    @Bean
    public IRule iRule(){
        //指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机权重)
        return new NacosRule();
    }
}
注意:此处有坑。 不能写在@SpringbootApplication注解的@CompentScan扫描得到的地方,否则自定义的配置类就会被所有的 
RibbonClients共享。 不建议这么使用,推荐yml方式

2)在启动类上利用@RibbonClient指定微服务及其负载均衡策略。

package com.wang;

import com.ribbon.RibbonConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * @BelongsProject: SpringCloudAlibabaLearn  @RibbonClient指定微服务及其负载均衡策略。
 * @BelongsPackage: com.wang.controller
 * @Author: wang fei
 * @CreateTime: 2023-01-16  16:54
 * @Description: TODO
 * @Version: 1.0
 */

@SpringBootApplication
@RibbonClients(value = {
        //在SpringBoot主程序扫描的包外定义配置类
        @RibbonClient(name="order-nacos",configuration = RibbonConfig.class)
})
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
    @Bean
    @LoadBalanced //负载均衡
    public RestTemplate restTemplate(RestTemplateBuilder  builder){
        RestTemplate restTemplate = builder.build();
        return restTemplate;
    }
}

方式2:通过修改配置文件实现(推荐)

修改application.yml
 #被调用的微服务名,指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重)
  stock-nacos:
    ribbon:
      NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon

5.自定义负载均衡策略

通过实现  IRule  接口可以自定义负载策略,主要的选择服务逻辑在 choose 方法中。
1)这里简单实现一个 随机负载均衡策略
package com.ribbon.rule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @BelongsProject: SpringCloudAlibabaLearn
 * @BelongsPackage: com.ribbon.rule
 * @Author: wang fei
 * @CreateTime: 2023-01-19  17:26
 * @Description: TODO 自定义规则,设置限流规则,自定义负载均衡策略
 * @Version: 1.0
 */
public class CustomRule extends AbstractLoadBalancerRule {
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    @Override
    public Server choose(Object o) {
        //随机负载均衡策略

        ILoadBalancer loadBalancer = this.getLoadBalancer();

        //获取当前请求的服务实例
        List<Server> reachableServers = loadBalancer.getReachableServers();
        int random = ThreadLocalRandom.current().nextInt(reachableServers.size());
        Server server = reachableServers.get(random);
        if (server.isAlive()) {
            return null;
        }
        return server;
    }
}

2)配置自定义的策略

修改application.yml

  stock-nacos:
    ribbon:
#     NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon
      ##自定义规则,设置限流规则,自定义负载均衡策略
      NFLoadBalancerRuleClassName: com.ribbon.rule.CustomRule

6. 饥饿加载

在进行服务调用的时候,如果网络情况不好,第一次调用会超时。 Ribbon默认懒加载,意味着只有在发起调用的时候才会创建客户端。
开启饥饿加载,解决第一次调用慢的问题:
ribbon:
  eager-load:
    # 开启ribbon饥饿加载
    enabled: true
    # 配置mall-user使用ribbon饥饿加载,多个使用逗号分隔
    clients: stock-nacos

实例工程:https://gitee.com/here-comes-brother-fei/ribbondemon.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/172415.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

9、jQuery

jQuery库&#xff1a;里面存在大量的JavaScript函数 官网&#xff1a;https://jquery.com/ 9.1 获取jQuery jQuery引入 cdn 引入 <script src"https://cdn.bootcss.com/jquery/3.4.1/core.js"></script>本地引入 <script src"lib/jquery-3.6.3.…

C语言练习——3

C语言练习——3一、 操作符练习1.1交换两个变量&#xff08;不创建临时变量&#xff09;1.2 打印整数二进制的奇数位和偶数位1.3[二进制中1的个数](https://www.nowcoder.com/questionTerminal/8ee967e43c2c4ec193b040ea7fbb10b8)1.4[两个整数二进制位不同个数](https://www.no…

【 java 反射下篇】java反射机制不难吧?来看看这篇

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

Element Plus 跟踪表格数据总数,包括查询、筛选等操作

前言 Element Plus的表格组件提供了筛选功能 前端项目中&#xff0c;如果表格使用的是后端分页&#xff0c;使用表格插件及分页器插件就可以了。这种情况下&#xff0c;前端的表格筛选被后端的分页条件查询取代了 另一种情况&#xff1a;不分页&#xff0c;直接查询所有数据…

Win7快速部署weblogic 12c

0x00 前言 需要一个漏洞中等数量的版本。 0x01 安装环境 版本操作系统Windows 7 64bitJDKjdk-8u101-windows-x64weblogic12.2.1.3 0x02 下载地址 JDK 下载地址 https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html jdk 1.8版本&#xff0c;文…

华为机试题:HJ16 购物单(python)

文章目录知识点详解1、input()&#xff1a;获取控制台&#xff08;任意形式&#xff09;的输入。输出均为字符串类型。2、print() &#xff1a;打印输出。3、strip()&#xff1a;删除字符串&#xff08;开头 / 结尾&#xff09;指定字符&#xff08;默认空格&#xff09;或字符…

两小时上手ActiveMQ

一、消息中间件概述 1.1 消息中间件产生的背景 在客户端与服务器进行通讯时.客户端调用后&#xff0c;必须等待服务对象完成处理返回结果才能继续执行。 客户与服务器对象的生命周期紧密耦合,客户进程和服务对象进程都都必须正常运行;如果由于服务对象崩溃或者网络故障导致用…

ceres学习笔记(四)

前言&#xff1a; 学习了pose_graph_2d部分&#xff0c;因为先学习了3维的pose_graph_3d部分&#xff0c;所以这个就比较容易。简单来说就是se2和se3的区别。整个的运行逻辑和3维部分的pose_graph_3d部分是一样的&#xff0c;概括为&#xff1a; 1.设置好两个type&#xff0c…

7、CenOS6安装Nginx

Nginx的安装与启动 什么是Nginx Nginx 是一款高性能的 http 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器。由俄罗斯的程序设计师伊戈尔西索夫&#xff08;Igor Sysoev&#xff09;所开发&#xff0c;官方测试 nginx 能够支支撑 5 万并发链接…

《早安隆回》的铁粉,深圳80后男子不计成本,收购袁树雄签名照

谁也没有想到&#xff0c;五十多岁并且离异多年的袁树雄&#xff0c;靠着一首《早安隆回》&#xff0c;一夜之间红遍大江南北。如今《早安隆回》这首歌曲&#xff0c;已经拥有了三百万流量&#xff0c;有人说袁树雄下辈子都吃喝不愁&#xff0c;他的前妻该后悔了。 《早安隆回》…

ue4c++日记4(控制pawn类的运动|创建游戏模式|)

目录 代码速查 调用数学公式 获取位置/设置位置 绑定玩家输入按键&#xff0c;UE4传值给函数进行处理 约束获得的值再输出 创建对象 对象绑定到xxx上 设定默认玩家 实例&#xff1a;sin函数实现往复运动 实例&#xff1a;删除c类 1.删掉cpp和.h文件 2.删编译好的文件B…

缓存Caffeine之W-TinyLFU淘汰测录

我们常见的缓存是基于内存的缓存&#xff0c;但是单机的内存是有限的&#xff0c;不能让缓存数据撑爆内存&#xff0c;所有需要缓存淘汰机制。https://mp.csdn.net/editor/html/115872837 中大概说明了LRU的缓存淘汰机制&#xff0c;以及基于LRU的著名实现guava cache。除了LRU…

Python学习笔记——类(面向对象)

Python中使用类&#xff08;class〕来实现面向对象编程。Python中的类, 具有面向对象编程的所有基本特征&#xff1a;允许多继承、派生类可以重写它父类的任何方法、方法可以调用父类中同名的方法, 对象可以包含任意数量和类型的数据成员。创建类Python中, 使用class语句来创建…

Python 第7章 文件与数据格式化 笔记1

编码&#xff1a;print(云.encode(utf8))print(b\xe4\xba\x91.decode(utf8))要注意代码的编码方式。7.1文件概述windows中一个文件的完标识&#xff1a;D:\Downloads\新建文本文档.txt依次是路径&#xff0c;文件名主干&#xff0c;拓展名。没有包含除了文本字符以外的其他数据…

【JavaEE初阶】第四节.多线程基础篇 Thread类的使用、线程的几个重要操作和状态

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、Thread类的常见构造方法 二、Thread 的几个常见属性 三、和线程相关的几个重要的操作 3.1 启动线程 - start() 3.2 中断线程 3.3 等待线程 - join() …

JDK 8新特性之基本发展史

目录 一&#xff1a;Java SE的发展历史 二&#xff1a;Open JDK来源 三&#xff1a;Open JDK 和 Oracle JDK的关系 四&#xff1a;Open JDK 官网介绍 小结 &#xff1a; 一&#xff1a;Java SE的发展历史 Sun公司在1991年成立了一个称为绿色计划( Green Project )的项目&a…

Ubuntu22.04 美化

一&#xff1a;安装软件 sudo apt install gnome-tweaks chrome-gnome-shell sudo apt install gtk2-engines-murrine gtk2-engines-pixbuf sudo apt install sassc optipng inkscape libcanberra-gtk-module libglib2.0-dev libxml2-utils 二&#xff1a;安装GNOME扩展插件…

Windows 卸载 Visual Studio Code、MinGW-w64、CMake

文章目录1.卸载 Visual Studio Code1.1 在控制面板中找到 Visual Studio Code 将其卸载1.2 删除之前安装过的插件1.3 删除用户信息和缓存信息2.卸载 MinGW-w642.1 删除之前解压出来的文件夹2.2 删除之前配置过的环境变量3.卸载 CMake3.1 删除之前解压出来的文件夹3.2 删除之前配…

无 Hadoop 环境部署 Kylin4

1相比于 Kylin 3.x&#xff0c;Kylin 4.0 实现了全新 spark 构建引擎和 parquet 存储&#xff0c;使 kylin 不依赖 hadoop 环境部署成为可能。无Hadoop环境也降低了运维成本&#xff0c;减少了系统资源占用。 以下操作基于centos7.6 单机版本 部署版本信息如下 JDK 1.8Hive …

【Javascript】面向对象编程,this,原型与原型链,类与实例,class,实现Map,stack,Queue ,Set

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录对象中的方法/thisthis使用bind函数原型原型链类与实例classclass语法补充Map实现Map实现stack实…