限流-漏桶算法、令牌桶算法

2023-11-02

1、问题

系统的某个接口访问量突然激增,没多久接口崩溃,形成连锁反应,导致整个系统崩溃。

如何应对这种情况呢?

为我们的接口加上“保险丝”,预防这种突发情况,接口压力过大,造成整个系统瘫痪。当接口流量过大时,我们可以通过拒绝访问或等待等机制,即限流。

2、限流常用算法

2.1 漏桶算法

漏桶算法(Leaky Bucket)是网络世界中流量整形(Traffic Shaping)或速率限制(Rate Limiting)时经常使用的一种算法,它的主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量。

漏桶可以看作是一个带有常量服务时间的单服务器队列,如果漏桶(包缓存)溢出,那么数据包会被丢弃。 在网络中,漏桶算法可以控制端口的流量输出速率,平滑网络上的突发流量,实现流量整形,从而为网络提供一个稳定的流量。

如图所示,把请求比作是水,水来了都先放进桶里,并以限定的速度出水,当水来得过猛而出水不够快时就会导致水直接溢出,即拒绝服务。

2.1.1 实现原理

  1. 队列接收到准备转发的数据包

  1. 队列被调度,得到转发机会,由于队列配置了流量整形,其中的数据包先进入漏桶

  1. 根据数据包到达漏桶的速率与漏桶的输出速率关系,确定数据包是否被转发:

  1. 如果到达速率 ≤ 输出速率,则漏桶不起作用

  1. 如果到达速率 > 输出速率,则考虑漏桶是否能承担瞬间流量

  1. 数据包到达的速率 - 漏桶流出的速率 ≤ 配置的漏桶突发速率,则数据包可被不延时的送出

  1. 数据包到达的速率 - 漏桶流出的速率 > 配置的漏桶突发速率,则多余的数据包被存储到漏桶中

  1. 暂存在漏桶中的数据包在不超过漏桶容量的情况下延时发出

  1. 数据包到达的速率 - 漏桶流出的速率 > 配置的漏桶突发速率,且数据包的数量已经超过漏桶的容量,则这些数据包将被丢弃

2.2 令牌桶算法

令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。

令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。从原理上看,令牌桶算法和漏桶算法是相反的,一个“进水”,一个是“漏水”。

Google的Guava包中的RateLimiter类就是令牌桶算法的解决方案。

2.2.1 实现原理

  • 令牌桶算法可控制发送到网络上数据的数目,并允许突发数据的发送

  • 大小固定的令牌桶可自行以恒定的速率源源不断地产生令牌:

  • 令牌桶中的每一个令牌都代表一个字节

  • 如果令牌桶中存在令牌,则允许发送流量

  • 如果令牌桶中不存在令牌,则不允许发送流量

  • 若令牌不被消耗,或被消耗速度小于产生速度,令牌就会不断地增多,直到把桶填满

  • 传送到令牌桶的数据包需要消耗令牌,不同大小的数据包,消耗的令牌数量不同

令牌桶算法的基本过程:

  • 每秒会有 r 个令牌放入桶中,或者说,每过 1/r 秒桶中增加一个令牌

  • 桶中最多存放 b 个令牌,如果桶满了,新放入的令牌会被丢弃

  • 当一个 n 字节的数据包到达时,消耗 n 个令牌,然后发送该数据包

  • 如果桶中可用令牌小于 n,则该数据包将被缓存或丢弃

3、对比

  • 漏桶算法强行限制数据的传输速率

  • 令牌桶算法在限制数据的平均传输速率的同时还允许某种程度的突发传输

3.1 漏桶算法举例

在某些情况下,漏桶算法不能够有效地使用网络资源,因为漏桶的漏出速率是固定的,所以即使网络中没有发生拥塞,漏桶算法也不能使某一个单独的数据流达到端口速率。因此,漏桶算法对于存在突发特性的流量来说缺乏效率

比如说存在两个系统A、B,公用一个网络,网络带宽为2M, A、B各分得1M,此时通过漏桶算法控制两个系统使用网络的速率,A、B系统使用网络的速率固定最大值为1M,无论A、B系统接受多少流量,但流出的速率都限制在最大1M,当网络中没有发生拥塞,也就是可能出现B系统可能空闲没有使用网络,对应分给B系统的1M带宽是空闲的,而A系统这一时刻接收了5M的流量,由于漏桶限流的存在,A只能使用1M带宽,我们的带宽有2M,此刻我们只能使用1M,也就是达不到带宽的最大速率,另外1M带宽是浪费的,因此不能充分利用,缺乏效率;当然从另一方面来讲也带来了好处,就是隔离性,A系统无论收到多大的流量冲击,对于B系统的无感的,不会因为流量冲击A,而B受到影响.

3.2 令牌桶算法举例

令牌桶算法能够在限制数据的平均传输速率的同时还允许某种程度的突发传输。

比如我们的目标现在是每秒钟处理10个请求,使用漏桶法,我们设置桶的大小为10,流出的速率为0.1s流出一个请求,我们可以达成我们的目标;而使用令牌桶的话,我们会设置每1s向桶中放入10个令牌,请求如果是平稳的,每0.1s过来一个请求,来十个,同样能达到我们的目标,这里所说的某种程度的突发传输是指,比如在一秒内前0.5s请求是平稳的,每0.1s来一个,但在0.6s的时候突发请求同时来个5个请求,此时令牌算法是可以承受这个突发流量的,并且让5个请求成功立刻同时通过,完成了所谓的某种程度的突发传输,而漏桶算法,也可以应对这种突发流量,但不同的是没有让5个请求同时立刻通过,而是缓冲在桶中,然后仍然以固定速率每0.1s通过一个。

3.3 总结

这两种算法,都可以实现流速的控制,1s处理10个请求,多于10个的请求都会被拒绝,但由于漏桶算法流出速率是一定的,所以请求可能会被缓冲在桶中,不能马上得到处理,从而徒增了等待时间,而对于令牌桶算法,没有这种等待时间,有令牌则通过,无令牌则抛弃。

4、应用场景

并不能说明令牌桶一定比漏洞好,它们使用场景不一样。令牌桶可以用来保护自己,主要用来对调用者频率进行限流,为的是让自己不被打垮。所以如果自己本身有处理能力的时候,如果流量突发(实际消费能力强于配置的流量限制),那么实际处理速率可以超过配置的限制。而漏桶算法,这是用来保护他人,也就是保护他所调用的系统。主要场景是,当调用的第三方系统本身没有保护机制,或者有流量限制的时候,我们的调用速度不能超过他的限制,由于我们不能更改第三方系统,所以只有在主调方控制。这个时候,即使流量突发,也必须舍弃。因为消费能力是第三方决定的。

总结起来:如果要让自己的系统不被打垮,用令牌桶。如果保证被别人的系统不被打垮,用漏桶算法。

参考:

https://blog.csdn.net/yin__ren/article/details/102798407

https://www.jianshu.com/p/c6b20845561a

https://blog.p2hp.com/archives/4351

https://www.cnblogs.com/junzi2099/p/14208640.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

限流-漏桶算法、令牌桶算法 的相关文章

  • 如何使用Spring WebClient进行同步调用?

    Spring Framework in 休息模板 https docs spring io spring framework docs current javadoc api org springframework web client R
  • NoInitialContextException:heroku 战争部署

    我一直在开发一个 J2EE 项目 并且在其中使用连接池 也通过部署在 heroku 上的数据库进行访问 我使用以下代码来设置 Connection 对象 Context initContext new InitialContext Cont
  • Guice 忽略注入构造函数参数上的 @Nullable

    我正在使用 Guice v 3 0 并且有一个值被注入到构造函数中 该值可以为 null 因此我在构造函数中使用 Nullable 来自 javax annotations 注释了该参数 public MyClass Parameter1
  • 获取文件的锁

    我想在对特定文件开始 threo read 时获取文件上的锁定 以便其他应用程序无法读取已锁定的文件并希望在线程终止时释放锁定文件 您可以获得一个FileLock https docs oracle com javase 8 docs ap
  • Android 中的列表(特别是 RecyclerView 和 CardView)如何工作

    请原谅我问这个问题 但我是 Android 开发新手 尽管我正在尝试了解developer android com 网站上的基础知识 但大多数示例 即使他们说它们是为 Android Studio 构建的 尚未设置为使用 Gradle 因此
  • 如何将jscrollpane添加到jframe?

    我有以下源代码 有人可以给我建议如何将 jscrollpane 添加到 jframe 上吗 我尝试了几次将其添加到 jframe 但没有任何进展 它甚至没有显示 public class Form3 JFrame jframe new JF
  • 在 Struts 2 中传递 URL 参数而不使用查询字符串

    我想使用类似的 URL host ActionName 123 abc 而不是像这样传递查询字符串 host ActionName parm1 123 parm2 abc 我怎样才能在 Struts 2 中做到这一点 我按照下面的方法做了
  • 为什么Iterator接口没有add方法

    In IteratorSun 添加了remove 方法来删 除集合中最后访问的元素 为什么没有add方法来向集合中添加新元素 它可能对集合或迭代器产生什么样的副作用 好的 我们开始吧 设计常见问题解答中明确给出了答案 为什么不提供 Iter
  • Android蓝牙java.io.IOException:bt套接字已关闭,读取返回:-1

    我正在尝试编写一个代码 仅连接到运行 Android 5 0 KitKat 的设备上的 目前 唯一配对的设备 无论我尝试了多少方法 我仍然会收到此错误 这是我尝试过的最后一个代码 它似乎完成了我看到人们报告为成功的所有事情 有人能指出我做错
  • 如何使用正则表达式验证 1-99 范围?

    我需要验证一些用户输入 以确保输入的数字在 1 99 范围内 含 这些必须是整数 Integer 值 允许前面加 0 但可选 有效值 1 01 10 99 09 无效值 0 007 100 10 5 010 到目前为止 我已经制定了以下正则
  • 如何通过注解用try-catch包装方法?

    如果应该在方法调用中忽略异常 则可以编写以下内容 public void addEntryIfPresent String key Dto dto try Map
  • 从直方图计算平均值和百分位数?

    我编写了一个计时器 可以测量任何多线程应用程序中特定代码的性能 在下面的计时器中 它还会在地图中填充花费了 x 毫秒的调用次数 我将使用这张图作为我的直方图的一部分来进行进一步的分析 例如调用花费了这么多毫秒的百分比等等 public st
  • 添加到列表时有没有办法避免循环?

    我想知道这样的代码 List
  • Java、Spring:使用 Mockito 测试 DAO 的 DataAccessException

    我正在尝试增加测试覆盖率 所以我想知道 您将如何测试 DAO 中抛出的 DataAccessExceptions 例如在一个简单的 findAll 方法中 该方法仅返回数据源中的所有数据 就我而言 我使用 Spring JdbcTempla
  • 用于缓存的 Servlet 过滤器

    我正在创建一个用于缓存的 servlet 过滤器 这个想法是将响应主体缓存到memcached 响应正文由以下方式生成 结果是一个字符串 response getWriter print result 我的问题是 由于响应正文将不加修改地放
  • Lombok @Builder 不创建不可变对象?

    在很多网站上 我看到 lombok Builder 可以用来创建不可变的对象 https www baeldung com lombok builder singular https www baeldung com lombok buil
  • 禁用 Android 菜单组

    我尝试使用以下代码禁用菜单组 但它不起作用 菜单项仍然启用 你能告诉我出了什么问题吗 资源 菜单 menu xml menu menu
  • Hadoop NoSuchMethodError apache.commons.cli

    我在用着hadoop 2 7 2我用 IntelliJ 做了一个 MapReduce 工作 在我的工作中 我正在使用apache commons cli 1 3 1我把库放在罐子里 当我在 Hadoop 集群上使用 MapReduceJob
  • ArrayList.clear() 和 ArrayList.removeAll() 有什么区别?

    假如说arraylist定义为ArrayList
  • 将对象从手机共享到 Android Wear

    我创建了一个应用程序 在此应用程序中 您拥有包含 2 个字符串 姓名和年龄 和一个位图 头像 的对象 所有内容都保存到 sqlite 数据库中 现在我希望可以在我的智能手表上访问这些对象 所以我想实现的是你可以去启动 启动应用程序并向左和向

随机推荐

  • 西门子S120常见故障F7900及其排查方法

    西门子S120作为一款高性能伺服驱动器 其强大的功能和优越的控制性能得到了广大用户的一致好评和青睐 借助强大的调试软件可以方便完成S120的调试 但对于初步接触和使用该产品的工程师来说 调试过程中往往会遇到一些简单的问题 由于缺乏经验而导致
  • 线性代数学习笔记4——矩阵的逆

    在进行矩阵的运算的时候 我们会发现我们没有定义矩阵的除法 但是经常又需要做类似的操作 因而我们引入矩阵的逆的概念 用以填补这个空白 矩阵的逆 由于我们在定义矩阵运算的时候只定义了数乘和矩阵乘法 而没有除法运算 和逆元的产生一样 我们为了定义
  • AutoDL算力平台租用GPU服务器+VSCode远程开发同步代码

    文章目录 一 关于租GPU服务器 二 使用XShell连接刚租的服务器 三 VSCode远程开发 四 VSCode SFTP插件实现本地代码与远程代码同步 一 关于租GPU服务器 理由 便宜好用 性价比高 https www autodl
  • Mybatis-plus3.5.1+版代码自动生成(FastAutoGenerator)

    该方法仅适用于mybatis plus 3 5 1 以上的版本 准备工作 Maven依赖 注意版本 该方法有可能因为版本的问题出现错误
  • 初学编程100个代码

    Java Python等主流编程语言如今火的不行 初学编程都有哪100个代码呢 笔者结合实际开发经验和同学们最迫切关注的技术热点 总结了100个常用的代码实现 具体如下 1 输出 Hello World print Hello World
  • 客户端负载均衡及透明应用切换(TAF)tnsnames failover=on

    客户端负载均衡及透明应用切换 TAF 这是客户端的一种功能 要在客户端的tnsnames ora中设置本地服务命名相应的参数 LOAD BALANCE ON和FAILOVER ON FAILOVER MODE参数 来启用客户端负载均衡和TA
  • springboot-mvc+扩展SpringMVC+@EnableWebMvc+修改自动化配置

    1 Spring MVC auto configuration https docs spring io spring boot docs 1 5 9 RELEASE reference htmlsingle boot features s
  • 定时器0工作方式1

    include
  • 在GPU上运行pytorch程序(指定单/多显卡)

    目录 1 使用CUDA VISIBLE DEVICES 2 使用cuda 和torch cuda set device 3 使用device 4 使用torch nn DataParallel 1 使用CUDA VISIBLE DEVICE
  • error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token

    头文件函数声明少了 分号 转载于 https www cnblogs com xuyh p 3794479 html
  • 分治算法例题

    分治算法例题 leetcode 23 给你一个链表数组 每个链表都已经按升序排列 请你将所有链表合并到一个升序链表中 返回合并后的链表 示例 1 输入 lists 1 4 5 1 3 4 2 6 输出 1 1 2 3 4 4 5 6 解释
  • WPF混合开发之WebView2(一) 简介及环境搭建

    目录 引言 WebView2系统要求 WebView2下载安装 结语 引言 在WPF开发中 经常会有混合开发的需求 即在WPF中加载网页 目前最常用也是最流行的方式是CefSharp 它的功能非常强大 可以提供较为完善的开发和使用体验 但是
  • 输出过压保护电路的设计思路

    输出过压保护电路的设计思路 开关电源在使用过程中会发生输出电压过高或者过低的现象 开关电源存在一个额定电压 如果超出额定电压就可能超出输出电容的耐压值 电源会因此发热击穿而烧毁甚至起火 因此设计出不同类型的保护电路 当控制电路失效或其他故障
  • nginx基础1——工作原理、安装配置、命令参数

    文章目录 一 基本了解 1 1 特性优点 1 2 功能应用 1 3 工作模块分类 1 4 模块配置方法 二 工作原理 三 安装与配置 四 常用命令 一 基本了解 nginx简介 nginx是一款轻量级的Web服务器 反向代理服务器及电子邮件
  • error:Spring项目启动卡死在parsed mapper file: */*.xml 无报错日志

    1 报错如下 Parsed mapper file file D 2401 JavaWorkSpace rmt dec service target classes mapper RirdMapper xml 2 解决办法 1 检查项目本身
  • LeetCode 477. Total Hamming Distance

    题目链接 点击这里 题意 两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量 计算一个数组中 任意两个数之间汉明距离的总和 class Solution public int totalHammingDistance vect
  • Nginx 性能优化有这篇就够了!

    目录 1 Nginx运行工作进程数量 Nginx运行工作进程个数一般设置CPU的核心或者核心数x2 如果不了解cpu的核数 可以top命令之后按1看出来 也可以查看 proc cpuinfo文件 grep processor proc cp
  • 饼图、柱形图、堆积柱、折线图、散点图,到底应该怎么选?

    随着数字经济的发展 各行业的数据都出现了爆炸式的增长 如何快速从海量数据中提取出有效信息 最大化地挖掘数据价值 是所有转型的企业都在面临的问题 想要快速直观地以易于理解 内容简单的方式了解相关数据 就需要数据可视化来帮忙 数据可视化作为当今
  • 微前端总结

    微前端 核心价值 微前端架构具备以下几个核心价值 技术栈无关 主框架不限制接入应用的技术栈 微应用具备完全自主权 独立开发 独立部署 微应用仓库独立 前后端可独立开发 部署完成后主框架自动完成同步更新 增量升级 在面对各种复杂场景时 我们通
  • 限流-漏桶算法、令牌桶算法

    1 问题 系统的某个接口访问量突然激增 没多久接口崩溃 形成连锁反应 导致整个系统崩溃 如何应对这种情况呢 为我们的接口加上 保险丝 预防这种突发情况 接口压力过大 造成整个系统瘫痪 当接口流量过大时 我们可以通过拒绝访问或等待等机制 即限