SpringCloud Alibaba Sentinel 与 SpringCloud Gateway 的限流有什么差别?(三种限流算法原理分析)

目录

一、Sentinel 与 Gateway 的限流有什么差别?

1.1、前置知识 - 四种常见的限流算法

1.1.1、Tips

1.1.2、计数器算法

1)固定窗口计数器算法

2)滑动窗口计数器算法

1.1.3、令牌桶算法

1.1.4、漏桶算法

1.2、解决问题


一、Sentinel 与 Gateway 的限流有什么差别?


1.1、前置知识 - 四种常见的限流算法

1.1.1、Tips

限流,就是指对服务器请求量做限制,避免因为突发的请求量过多,导致服务器宕机.  

比如,我们的服务器只能抗住每秒 1000 的请求量,但此时突然有 10000 的请求量来了,那么就需要把你这么大的请求量拦下来,按照服务能够承载的流量去放行,起到一个流控的效果.

如何实现呢,就来看看这主流的三种限流算法~

1.1.2、计数器算法

计数器算法又包括两种算法,如下:

1)固定窗口计数器算法

a)首先,他会将时间划分成多个窗口(时间窗口也被称为 interval),然后呢每一个窗口都会维护一个计数器,一旦有一个请求在这个窗口出现,计数器就会加一.

b)随着这一时刻突然增多,那么这个计数器就会越来越大,所以限流就是在设置这个计数器的阈值,数量超过阈值的请求就会被丢弃.

例如,窗口大小是 1000ms,阈值是3.  那么如果这 1000 ms 内的请求来了 4 个,那么超过阈值的那一个请求就会被丢弃.

这种算法会有一点缺陷:

例如,窗口大小是 1000ms,阈值是3.  我在 4000ms ~ 4500ms 之间一个请求都没有,然后在 4500ms ~ 5000ms 之间来了三个请求,你看,这是没问题的吧...

接着在 5000ms ~ 5500ms 之间又来了三个请求,并且 5500ms ~ 6000ms 之间也没有请求来,那么这一看,我这个窗口里也没超过呀.

但是!仔细思考一下,4500ms ~ 5500ms 之间不也是 1s 么,等于说你这 1s 放行了 6 个请求,如果你系统的最大 qps 是 3(每秒最多处理 3 个),岂不是就搞崩了.

如下图:

那么为了解决上述问题,就有了滑动窗口计数器算法~

2)滑动窗口计数器算法

a)滑动窗口计数算法中,不光有窗口,还会把窗口划分成更小的时区,例如窗口大小是 1000ms,分区比如是 2,那么就会把 1s 按照两个区间来划分,每个小的区间大小就是 500ms,这个区间就是用来统计请求个数的

b)真正的窗口呢,我们还是按照 1s 来统计(qps 的意义就是每秒请求量).

c)窗口也是会移动的,移动的方式由当前时间来决定窗口的范围,就是用当前请求到达的时间 减 时间窗口(interval)之后的第一个时区算起.

例如,时间窗口大小是 1000ms,分区是 500ms,qps 是 3.  假设有三个请求,分别是 900ms、 1250ms、1300 ms,此时计算窗口大小就是 1300ms ~ 1300ms - 1000ms 的下一个时区,也就是  500 ~ 1500ms,一共有三个请求.  如果400ms 又来了一个请求,是不是按照滑动窗口的计算方式就超出了,因此就会抛弃掉.

但是如果按照固定窗口大小计算,就有可能正好在 500 ~ 1500ms 这个区间也是一秒,因此就会放行通过,那这就相当于多放行了一个请求!

那么滑动窗口就一定没问题么?

不一定哦,假设 1600ms 这个时候又来了一个请求,就要出问题了!乍一看,窗口区间是 1600ms ~ 1600ms - 1000ms 的下一个时区,也就是 1600ms ~ 1000ms,只放行了三个请求.

但是仔细看一下,1600ms 和 900ms 的这个请求之间差多少秒?是不是 700ms,也就是说,这700ms 的时间,连续放行了 4 个请求!

因此,滑动窗口知识解决了固定窗口的小问题,而如果几个请求之在窗口之间挨的很近,依然会出问题.  这个时候,你就可以把这个时区再继续分的更细一点,就能解决了.   例如 时区大小是 250ms,那么窗口区间就是 1600ms ~ 750ms,而此时一看窗口里面有 4 个请求,就会把最后来的请求给抛弃了~

如下图:

1.1.3、令牌桶算法

a)令牌桶算法就说,有一个桶,这个桶里会以固定的速率去生成令牌(这个速率实际上就是 qps).

b)当这个桶满了以后,就会把多余的令牌丢弃.

c)每一个请求来的时候都会去申请一个令牌,如果桶中没有令牌,请求就会被丢弃.

例如,qps 是5,也就是生成 令牌的速率是每秒 5 个,而此时桶中有 5 个令牌,但是忽然有 6 个请求同时到来,那么多出来的请求就会被丢掉.

令牌桶算法的缺陷:

思考这样一个问题,假设桶的容量是 5,每秒生成 5 个令牌,但非常神奇的是,第一秒的时候一个请求都没有来,而第二秒突然来了 10 个请求,那么首先会先去桶里把存的 5 个令牌拿走,这 5 个请求瞬间就过去了,而第二秒的时候又要生成 5 个令牌,剩下的 5 个令牌是不是也能过去.

这就超过阈值了...

他的缺陷同时也是一个好处:

如果我们设置令牌的速度不是我们服务器的上限,而是一个平均值,偶尔超出也不会把服务压垮,那么令牌桶就可以很好的处理突发的请求情况(请求带有波动性的).

例如服务器的最大并发能力是 6,我设置 qps 为 3(令牌生成速度),如果说第一秒没有请求来,那么第二秒的时候来了 6 个请求,此时就可以桶里有 6 个令牌,就都能都放行处理了,不会造成请求的丢失.

令牌桶的真正底层实现:

虽然我们讲他是利用一个桶,每秒钟生成多少令牌,但是代码真正的实现可不是这样,因为你还要弄个定时器去生成,很麻烦.

令牌桶的代码实现思路是这样的:

  1. 这个桶的话实际上里面并不会生成令牌,而是记录上一个请求来的时间,另外还记录了当前还有几个令牌了.
  2. 只要记录了这两样东西,那么当请求来了以后,我只需要计算这个请求和上一个请求之间的时间差,如果时间差在小于令牌在这段时间生成的数量,就可以放行通过

例如我每秒生成 5 个令牌,那么假设来了两个请求,我就可以计算以下他两的时间差,比如说是 0.2 秒,那么当前的令牌个数就可以认为是 0.2 * 5 = 1,因此此时只有一个令牌,只能处理一个请求,处理不了这第二个.

1.1.4、漏桶算法

a)漏桶算法呢也有一个桶,只不过不是用来存令牌的,而是用来存请求的.

b)当请求来了,就会把它当成一滴水放到桶里面去,然后漏桶就会以固定的速率向漏出请求.

c)如果桶满了,多余的请求就会被丢弃.

这就像是有一个桶,但是桶下面开了一个小口,当你往桶里倒水的时候,水就会以固定的速率从这个固定大小的小口流出.

漏桶算法的优势:

  • 应对突发的请求:假如漏桶的处理速度是每 3s 一个请求,但是如果突发来了 10 个请求,没关系,我在桶里先存起来,后面慢慢处理就可以.
  • 流量永远是平滑的:不管你每秒是来了 10 个还是 100 个请求,只要我桶够大,那么放出去的速度永远都是固定的,也就是说他处理请求的速度一直是一条直线.
  • 对比令牌桶:对于令牌桶来说,如果请求忽高忽低,这个时候令牌桶就没办法保证平滑,他有可能会出现忽高忽低的情况,因为前一秒令牌没有用完可以累计,在下一秒就有可能出现一次性被消耗完的情况.

漏桶算法的实现原理:

a)漏桶算法的请求实际上就是遵循先进先出,那么用的容器肯定就是队列.

b)当请求来的时候,这些请求就会按照时间间隔依次执行.

c)并且会有一个预期等待时间,实际上就是桶的大小.  当新的请求到来时,就会将桶中所有请求的等待时间加起来,然后再加上新的请求,如果大于预期等待时间,这个新的请求就会被抛弃.

例如,桶的预期等待时间是 2000ms(桶的大小),qps 是 5(每秒通过 5 个请求),也就相当于 200ms 处理一个请求.

突然某一时刻同时来了很多请求,那么第一个请求进来时,可以立即被执行,因此等待时间就是 0ms,第二请求就需要排队了,就是 200ms 的时候会被执行,往后以此类推.   当队列中所有请求的等待时间加起来等于 2000ms 的时候(预期等待时间),此时再来的请求就会被拒绝.

1.2、解决问题

明白上述的四种算法,回答这个问题就游刃有余了~

这个时候你就可以说,那么首先呢常见的有 3 种限流算法,分别是 计数器算法、令牌桶算法、漏桶算法.  Gateway 采用的是基于 Redis 实现的令牌桶算法(key value 就是一个桶).

而 Sentinel 内部实现的比较复杂:

  • 默认限流模式是基于滑动时间窗口算法
  • 排队等待的限流模式则基于漏桶算法:因为漏桶算法本身就是一种排队嘛,请求来了,如果前面还有请求没被执行,就排队,并且按照固定的频率去执行.
  • 而热点参数限流则是基于令牌桶算法:热点参数的特点就是针对每个一个参数单独去统计,那么你可以看作是一个接口,比如查询商品,将来商品的参数可能就是成千上万,如果采用滑动窗口的方式,那就需要进行时间分区,并每个分区种都有一个计数器来统计,那么对内存的消耗是非常大的.   如果使用令牌桶,就只需要记住这个参数对应的令牌即可(上一个请求来的时间).

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

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

相关文章

Qt Designer教程

文章目录 创建一个 ui 文件选择控件Qt Designer基本控件介绍1、Layouts1.1、Layouts 布局1.2、参数配置 2、Spacers2.1、 Spacers 弹簧介绍2.2、 参数设置 3、Buttons 按键3.1、 Buttons 按键分类 4、Item Views(Model-Based) 项目视图(基于模型)4.1、 B…

12.for 条件循环语句 (3)

for 循环语句 允许脚本一次性读取多个信息,然后逐一对信息进行操作处理。当要处理的数据有范围时,使用for循环语句。 使用 for 循环语句从列表文件中读取多个用户名,然后为其逐一创建用户账户并设 置密码。首先创建用户名称的列表文件users.…

android studio从空白开始

对我来说,真正的第一步是清理电脑C盘。从剩余8G清理到25G,把原来看不顺眼又不敢删的文件夹和软件全删了,删爽了的后果就是,用两天的时间在把一些环境配置慢慢装回来,node.js,jdk,npm。努力把它们…

密码学中的承诺原语(Commitment Scheme)

1背景介绍 让我们考虑以下情况:Alice在佳士得(Christies)购买Banksy的最后一件杰作,在这之前,她会确保艺术品在售出后不会被销毁。 佳士得选择了维克里封闭竞标的拍卖方式,这是一种相当常见的做法&#x…

Vue+Element(el-upload+el-form的使用)+springboot

目录 1、编写模板 2、发请求调接口 3、后端返回数据 1.编写实体类 2.Controller类 3、interface接口(Service层接口) 4.Service(接口实现) 5、interface接口(Mapper层接口) 6、xml 4、upload相关参…

前端 防止浏览器提示记住密码以及自动填充密码

当前端 <input /> 的 type’password‘ 时&#xff0c;浏览器为了优化用户体验&#xff0c;会在表单提交后提示用户记住密码 如果不想要这样的行为&#xff0c;最简单的当然是提示用户自己在浏览器设置中进行相关配置 如果希望在代码层面阻止浏览器提示是否记住密码或者…

.git 文件夹结构解析

.git 文件夹结构解析 在这篇文章就让我们来看看这个 Git 仓库里的文件分别都是用来干什么的&#xff0c;以及在执行了相关的 Git 命令后这些文件会如何响应。 hooks&#xff08;钩&#xff09;&#xff1a;存放一些shell脚本info&#xff1a;存放仓库的一些信息logs&#xff…

ChromeDriver谷歌驱动最新版安装120/121/122

chromeDriver最新版本下载 最新驱动 https://googlechromelabs.github.io/chrome-for-testing/参考&#xff1a; https://blog.csdn.net/m0_57382185/article/details/134007615

ORM-02-Hibernate 对象关系映射(ORM)框架

拓展阅读 The jdbc pool for java.(java 手写 jdbc 数据库连接池实现) The simple mybatis.&#xff08;手写简易版 mybatis&#xff09; Hibernate Hibernate ORM 允许开发者更轻松地编写那些数据在应用程序进程结束后仍然存在的应用程序。 作为一个对象关系映射&#xff08…

基于蝗虫优化的KNN分类特征选择算法的matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 KNN分类器基本原理 4.2 特征选择的重要性 4.3 蝗虫优化算法&#xff08;GOA&#xff09; 5.完整程序 1.程序功能描述 基于蝗虫优化的KNN分类特征选择算法。使用蝗虫优化算法&#xff…

C++入门语法———命名空间,缺省参数,重载函数

文章目录 一.命名空间1.存在意义2.语法使用1.定义命名空间2.使用命名空间的三种方式 二.缺省参数1.全缺省参数2.半缺省参数 三.重载函数1.定义2.重载原理———名字修饰 一.命名空间 1.存在意义 C命名空间的主要意义是为了避免命名冲突&#xff0c;尤其是在大型项目中可能存在…

“高级SPA项目构建与路由实现“

目录 引言1. SPA项目构建1.1 安装vue-cli,webpack1.2 创建 Vue.js项目1.3 “一问一答”模式1.4 启动项目 2. SPA项目完成路由3. 基于SPA项目完成嵌套路由总结 引言 在现代Web开发中&#xff0c;单页应用&#xff08;SPA&#xff09;已经成为一种流行的开发模式。SPA通过在前端…

优优嗨聚:美团代运营服务,为商家赋能,打造流量转化的秘密武器

随着互联网的飞速发展&#xff0c;人们越来越依赖线上平台进行消费。作为国内领先的电商平台之一&#xff0c;美团吸引了众多商家入驻。然而&#xff0c;如何在竞争激烈的美团平台上脱颖而出&#xff0c;成为了商家们面临的一大挑战。此时&#xff0c;美团代运营服务应运而生&a…

HTML5和CSS3的新特性

HTML5的新特性主要是针对于以前的不足&#xff0c;增加了一些新的标签、新的表单和新的表单属性等 1&#xff0c;HTML5新增的语义化标签 <header> 头部标签 <nav> 导航标签 <article> …

《WebKit 技术内幕》学习之九(4): JavaScript引擎

4 实践——高效的JavaScript代码 4.1 编程方式 关于如何使用JavaScript语言来编写高效的代码&#xff0c;有很多铺天盖地的经验分享&#xff0c;以及很多特别好的建议&#xff0c;读者可以搜索相关的词条&#xff0c;就能获得一些你可能需要的结果。同时&#xff0c;本节希望…

记录centos安装nginx过程和问题

今天在centos上安装了nginx&#xff0c;遇到了些问题&#xff0c;记录一下。 使用yum直接安装的话安装的版本是1.20.1&#xff0c;使用源码包安装可以装到1.25.0&#xff08;最新稳定版&#xff09;。很有意思的一点是两种安装方法下安装的路径是不同的&#xff0c;且源码安装…

Java 面向对象案例 03(黑马)

代码&#xff1a; public class phoneTest {public static void main(String[] args) {phone [] arr new phone[3];phone p1 new phone("华为",6999,"白色");phone p2 new phone("vivo",4999,"蓝色");phone p3 new phone("苹…

手把手教你用深度学习做物体检测(一): 快速感受物体检测的酷炫

我们先来看看什么是物体检测&#xff0c;见下图&#xff1a; 如上图所示&#xff0c; 物体检测就是需要检测出图像中有哪些目标物体&#xff0c;并且框出其在图像中的位置。 本篇文章&#xff0c;我将会介绍如何利用训练好的物体检测模型来快速实现上图的效果&#xff0c;这里…

Pyside6中QTableWidget使用

目录 一&#xff1a;介绍&#xff1a; 二&#xff1a;演示 一&#xff1a;介绍&#xff1a; 在 PySide6 中&#xff0c;QTableWidget 是一个用于展示和编辑表格数据的控件。它提供了在窗口中创建和显示表格的功能&#xff0c;并允许用户通过单元格来编辑数据。 要使用 QTabl…