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 内部实现的比较复杂:

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何通过 Nginx 反向代理提高网站安全性和性能?

如何通过 Nginx 反向代理提高网站安全性和性能? 引言Nginx 反向代理的基本原理什么是反向代理?反向代理的工作方式反向代理的好处 配置 Nginx 反向代理的基本步骤1. 安装 Nginx2. 编辑 Nginx 配置文件3. 设置反向代理配置4. 测试并重启 Nginx 提高安全性…

NineData支持制定安全、可靠的SQL开发规范

在和数据库打交道中,不管是数据库管理员(DBA)还是开发人员,经常会做一些CURD操作。因为每个人对数据库的了解程度不一样,所以在项目上线时,往往还需要专职人员对数据库的CURD操作进行审核,确保C…

第21课 在Android Native开发中架起java与c++互通的桥梁

在开始本节课,我尝试把项目拷贝到另一台电脑上以便继续工作,但出现了大量的“could not be resolved”问题,尝试包含新的include路径也无法解决该问题,最后删除了项目的Native Support,然后重新添加Native Support才解…

1.19号网络

超时检测 概念 1> 在网络通信中,有很多函数是阻塞函数,会导致进程的阻塞,例如:accept、recv、recvfrom、等等 2> 为了避免进程在阻塞函数处,无休止的等待,我们可以设置一个超时时间,当…

unity学习笔记----游戏练习05

一、阳光的收集和搜集动画开发 1.收集阳光的思路:当鼠标点击到阳光的时候,就可以进行收集了。可以通过为添加一个碰撞器来检测Circle Collider 2D 编写脚本: 在SunManager中写一个增加阳光的方法 //增加阳光 public void AddSubSun(in…

如何利用streamlit 將 gemini pro vision 進行圖片內容介紹

如何利用streamlit 將 gemini pro vision 進行圖片內容介紹 1.安裝pip install google-generativeai 2.至 gemini pro 取 api key 3.撰寫如下文章:(方法一) import json import requests import base64 import streamlit as st 讀取圖片檔案,並轉換成 Base64 編…

51-15 视频理解串讲—TimeSformer论文精读

今天读的论文题目是Is Space-Time Attention All You Need for Video Understanding? Facebook AI提出了一种称为TimeSformer视频理解的新架构,这个架构完全基于transformer,不使用卷积层。它通过分别对视频的时间和空间维度应用自注意力机制&#xff…

SpringBoot 3.1.7 集成Kafka 3.5.0

一、背景 写这边篇文章的目的,是记录我在集成kafka客户端遇到的一些问题,文章会记录整个接入的过程,其中会遇到几个坑,如果需要最终版本,直接看最后一节就行了,感觉Spring-Kafka的文档太少了,如…

linux更新内核

内核介绍 官网链接:https://kernel.org 内核下载库: https://mirrors.edge.kernel.org/pub/linux/kernel/ 更新软件源 rootcary:~# apt-get update rootcary:~# sudo apt-get install libncurses5-dev build-essential kernel-package flex bison libelf-dev libssl-dev 下…

大数据学习之Redis、从零基础到入门(一)

目录 一、Redis入门概述 1. 是什么? 官方解释: 2. 能干嘛? 2.1 主流功能与应用 2.1.1分布式缓存 2.1.2内存存储和持久化(RDBAOF) 2.1.3高可用架构搭建 2.1.4缓存穿透、击穿、雪崩 2.1.5分布式锁 2.1.6队列 2.2 总体功能概括 2.3…

基于Java SSM框架实现在线考试系统项目【项目源码+论文说明】

基于java的SSM框架实现在线考试系统演示 摘要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识&#…

面试知识点:notify是随机唤醒线程吗(唤醒线程顺序)?

做 Java 开发的小伙伴,对 wait 方法和 notify 方法应该都比较熟悉,这两个方法在线程通讯中使用的频率非常高,但对于 notify 方法的唤醒顺序,有很多小伙伴的理解都是错误的,有很多人会认为 notify 是随机唤醒的&#xf…

Vue实现图片预览,侧边栏懒加载,不用任何插件,简单好用

实现样式 需求 实现PDF上传预览,并且不能下载 第一次实现:用vue-pdf,将上传的文件用base64传给前端展示 问题: 水印第一次加载有后面又没有了。当上传大的pdf文件后,前端获取和渲染又长又慢,甚至不能用 修…

2. figure 常见属性

2. figure 常见属性 一 figsize二 dpi三 facecolor四 edgecolor五 frameon 数据可视化是数据分析中不可或缺的一环,而Matplotlib作为Python中最流行的绘图库之一,扮演着重要的角色。在Matplotlib中,matplotlib.figure.Figure对象是构建图形的…

MyBatis详解(2)-- mybatis配置文件

MyBatis详解&#xff08;2&#xff09; mybatis配置文件 mybatis配置文件 1.构建SqlSessionFactory的依据。 2.MyBatis最为核心的内容&#xff0c;对MyBatis的使用影响很大。 3.配置文件的层次顺序不能颠倒&#xff0c;一旦颠倒会出现异常。 < c o n f i g u r a t i o n…

openresty 安装, nginx与 openresty

openresty VS nginx Nginx 是一款高性能的 Web 服务器和反向代理服务器&#xff0c;具备基础的功能如HTTP服务、负载均衡、反向代理以及动静分离等。它是许多互联网应用的核心组件&#xff0c;因其模块化和可扩展的设计而受到欢迎。1 OpenResty 是基于 Nginx 的 Web 平台&…

C++入门篇章1(C++是如何解决C语言不能解决的问题的)

目录 1.C关键字(以C98为例)2.命名空间2.1 命名空间定义2.2命名空间使用 3.C输入&输出4.缺省参数4.1缺省参数概念4.2 缺省参数分类 5. 函数重载5.1函数重载概念5.2 C支持函数重载的原理--名字修饰(name Mangling) 1.C关键字(以C98为例) C总计63个关键字&#xff0c;C语言32…

【操作系统基础】【CPU访存原理】:寄存 缓存 内存 外存、内存空间分区、虚拟地址转换、虚拟地址的映射

存储器怎么存储数据、内存空间分区、虚拟地址转换 计算机的存储器&#xff1a;寄存 缓存 内存 外存&#xff08;按功能划分&#xff09; 计算机的处理器需要一个存储器来存储大量的指令和数据以便自己不断取指执行和访问数据。 内存&#xff08;内存就是运行内存&#xff0c…

利用git上传本地文件

1、建立仓库 2.然后刷新网站&#xff0c;获取下载链接&#xff0c;备用。 3、接下来在本地创建一个文件夹&#xff0c; 4、把github上面的仓库克隆到本地 git clone https://github.com/xxxxx&#xff08;https://github.com/xxxxx替换成你之前复制的地址&#xff09; 5、把…

简单快速取消AlertDialog的白色背景框,AlertDialog设置圆角背景

问题描述&#xff1a; 产品需求弹出的提示框是圆角&#xff0c;使用shape 设置圆角背景后&#xff0c;弹出的AlertDialog提示框四个角有白色的背景&#xff0c;据分析这个背景是 AlertDialog 父组件的背景色。 解决方法&#xff1a; 将Dialog的背景设置为透明色&#xff0c;代…