一文搞懂常见限流算法:计数器、滑动窗口、漏桶、令牌桶

news2025/1/21 21:50:04

文章目录

  • 1、计数器算法
  • 2、滑动窗口算法
  • 3、漏桶算法(漏斗算法)
  • 4、令牌桶算法
  • 5、限流算法总结
  • 6、限流组件

📢:在开发高并发系统时,有三把利器用来保护系统:缓存、降级和限流。

限流在很多场景中用来限制并发和请求量,比如说秒杀抢购,保护自身系统和下游系统不被巨型流量冲垮等。你要开发一个限流的框架,那么必不可少的就是要选择一种合适的限流算法。限流算法很多,常见的有几类分别是:计数器算法滑动窗口算法漏桶算法令牌桶算法,具体视业务场景,统计的精准度,限流维度而定。下面逐一讲解。

1、计数器算法

计数器算法是限流算法里最简单也是最容易实现的一种算法。主要用来限制一定时间内的总并发数,计数器限流只要一定时间内的总请求数超过设定的阀值则进行限流,是一种简单粗暴的总数量限流,而不是平均速率限流。比如数据库连接池、线程池、秒杀的并发数;

优点:简单粗暴,单机在Java中可用Atomic等原子类或Semaphore,分布式就用Redis incr。

eg:我们规定,对于A接口来说,我们1分钟的访问次数不能超过100个。那么在一开始的时候,我们可以设置一个计数器counter,每当一个请求过来的时候,counter就加1,如果counter的值大于100并且该请求与第一个请求的间隔时间还在1分钟之内,那么说明请求数过多,限流;如果该请求与第一个请求的间隔时间大于1分钟,且counter的值还在限流范围内,那么就重置 counter
在这里插入图片描述

缺点:有一个十分致命的问题,那就是临界问题

eg:假设第1分钟中的第59秒的时候,来了100个请求,这个时候是没有超过100的限制。然后第2分钟的第1秒来了100个请求,相隔几毫秒,一下子进来200个请求,明显大于我们的限流阈值100。也就是说在时间窗口的重置节点处突发请求,可以瞬间超过我们的速率限制。用户有可能通过算法的这个漏洞,瞬间压垮我们的应用。所以这个算法不够完美是不是?
在这里插入图片描述

为了解决这个临界区问题,我们引入了滑动窗口算法

2、滑动窗口算法

滑动窗口,又称rolling window。上边提到的计数器算法中,比如限制1分钟内的访问次数,那么这个1分钟就是一个固定的时间窗口,而滑动窗口是将固定窗口再进行细分成多个窗口。

eg:比如将1分钟的固定窗口细分成6个窗口,那么每个窗口的时间就是10秒。如图整个红色的矩形框表示一个时间窗口,窗口是一直滑动的,每过10秒,我们的时间窗口就会往右滑动一格。按照上边我们的假设:假设第1分钟中的第59秒的时候,来了100个请求,落到灰色格子里,而第2分钟的1:00到达的100个请求会落在橘黄色的格子中,而这时我们的时间窗刚好检测到整个1分钟内(红色框),总请求数量一共是200个,超过了限定的100个,所以此时能够检测出来触发了限流。

Spring Cloud 中的熔断框架 Hystrix,以及 Spring Cloud Alibaba 中的Sentinel 都采用滑动窗口来做数据统计。

优点:减少了临界值带来的并发超过阈值的问题。

在这里插入图片描述

由此可见,当滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。

3、漏桶算法(漏斗算法)

漏桶算法相对前面的计数算法更加柔性,它的原理也很简单,它是一种恒定速率的限流算法,不管请求量是多少,服务端的处理效率是恒定的。漏桶限制的是请求的流出速率。漏桶中装的是请求。

优点:是能够以固定的速率去控制流量,稳定性比较好。

可以认为就是我们常用的漏斗注水漏水的过程。漏桶接受以任意速率流入的水,并且以固定速率将水流出。当水超过桶的容量时,会被溢出,也就相当于被丢弃。

漏桶算法原理与消息队列思想有些类似,都是进行削峰填谷,经过漏桶后请求就能匀速平滑的流出。它是一种恒定速率的限流算法,不管请求量是多少,服务端的处理效率是恒定的。基于 MQ 来实现的生产者消费者模型,其实算是一种漏桶限流算法。
在这里插入图片描述

缺点:就是无法应对突发流量的来袭,以及处理请求会有延迟

eg:假设你的漏桶出口固定了每秒钟只能通过100个请求,如果此时有150个请求,无论你后方的系统能不能抗住这150个请求,通过漏桶算法都会将另外50个请求进行拦截,只能等前面的100个请求结束后才能继续放行剩下的50个请求,无法应对突发流量的来袭。

面对突发请求,服务的处理速度和平常一样,这其实不是我们想要的。我们更想要的是面对突发流量时,在系统平稳运行的同时又能更快的处理请求,而不是一直按照统一的速率来处理。漏桶算法,可能更多的用来保护别人的接口。另外,漏桶中由于请求是暂存在桶中的,所以请求什么时候能被处理,则是有延时的,这并不符合互联网业务低延时的要求。

4、令牌桶算法

令牌桶是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌,填满了就丢弃令牌,请求是否被处理要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求。在流量低峰的时候,令牌桶会出现堆积,因此当出现瞬时高峰的时候,有足够多的令牌可以获取,令牌桶允许一定程度突发流量,只要有令牌就可以处理,支持一次拿多个令牌。令牌桶中装的是令牌。
在这里插入图片描述

网关层面的限流、或者接口调用的限流,都可以使用令牌桶算法,像 Google 的Guava,和 Redisson 的限流,都用到了令牌桶算法。

优点:令牌桶算法是对漏斗算法的一种改进,除了能够起到限流的作用外,还允许一定程度的流量突发。

与漏桶算法相比,有可能导致短时间内的请求数上升(因为拿到令牌后,就可以访问接口,存在一瞬间将所有令牌拿走的情况),但不会有计数算法那样高的峰值(因为令牌数量是匀速增加的)。所以在应对突发流量的时候令牌桶表现的更佳。

一般自己调用自己的接口,接口会有一定的伸缩性,令牌桶算法,主要用来保护自己的服务器接口。

缺点:例如令牌桶,假如系统上线时没有预热,那么可能会出现由于此时桶中还没有令牌,而导致请求被误杀的情况;

5、限流算法总结

上面我们已经了解了每个限流算法的的特点,并且类比了一些应用场景。综上可知,虽然漏桶、令牌桶对比时间窗口类算法对流量的整形效果更好,但是它们也有各自的缺点。

令牌桶、漏桶算法更适合阻塞式限流的场景,即后台任务类的限流。

而基于时间窗口的限流则更适合互联网实施业务限流的场景,即能处理快速处理,不能处理及时响应调用方,避免请求出现过长的等待时间。

6、限流组件

一般而言我们不需要自己实现限流算法来达到限流的目的,不管是接入层限流还是细粒度的接口限流其实都有现成的轮子使用,其实现也是用了上述我们所说的限流算法。

比如Google Guava 提供的限流工具类 RateLimiter,是基于令牌桶实现的,并且扩展了算法,支持预热功能。

阿里开源的限流框架Sentinel 中的匀速排队限流策略,就采用了漏桶算法。

Nginx 中的限流模块 limit_req_zone,采用了漏桶算法,还有 OpenResty 中的 resty.limit.req库等等。

在这里插入图片描述

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

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

相关文章

为C# Console应用化个妆

说到Windows的cmd,刻板印象就是黑底白字的命令行界面。跟Linux花花绿绿的界面比,似乎单调了许多。但其实C#开发的Console应用也可以摆脱单调非黑即白的UI。 最近遇到个需求,要在一堆纯文本文件里找指定的关键字(后续还要人肉判断…

25 Linux可视化-Webmin和bt运维工具

25 Linux可视化-Webmin和bt运维工具 文章目录 25 Linux可视化-Webmin和bt运维工具25.1 Web运行环境简介25.2 Webmin的安装及使用25.2.1 安装webmin25.2.2 Webmin使用演示 25.3 bt(宝塔)的安装及使用25.3.1 安装宝塔25.3.2 宝塔Web登录Linux服务器25.3.3 找回宝塔登录密码 学习视…

每日两题 226翻转二叉树 1026节点与其祖先之间的最大差值

226 题目 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2: 输入:root [2,1,3] 输出:[2,3,1]示…

NineData X SelectDB 联合发布会,即将上线!

8月30日晚上19:00,由 NineData 和 SelectDB 共同举办的主题为“实时数据驱动,引领企业智能化数据管理”的线上联合发布会,即将如期上线! 本次发布会将聚焦于实时数据仓库技术和数据开发能力,展示SelectDB新一代实时数据…

安装win11卡在联网界面(已解决)

安装win11卡在联网界面(已解决) 1. 问题描述2. 解决方法参考 1. 问题描述 windows11新电脑第一次开机或系统重装之后配置系统时到联网界面出现如下图情况,没有可以选择的选项,或者说卡在联网界面。 2. 解决方法 按 shiftF10 弹…

Kubernetes(七)修改 pod 网络(flannel 插件)

一、 提示 需要重启服务器 操作之前备份 k8s 中所有资源的 yaml 文件 如下是备份脚本,仅供参考 # 创建备份目录 test -d $3 || mkdir $3 # $1 命名空间 # $2 资源名称: sts deploy configMap svc 等 # $3 资源备份存放的目录名称for app in kubec…

文心一言接入Promptulate,开发复杂LLM应用程序

简介 最近在尝试将文心一言的LLM能力接入Promptulate,故写了一篇博客记录一下,Promptulate 是 Promptulate AI 旗下的大语言模型自动化与应用开发框架,旨在帮助开发者通过更小的成本构建行业级的大模型应用,其包含了LLM领域应用层…

k8s的交付与部署案例操作

一 k8s的概念 1.1 k8s k8s是一个轻量级的,用于管理容器化应用和服务的平台。通过k8s能够进行应用的自动化部署和扩容缩容。 1.2 k8s核心部分 1.prod: 最小的部署单元;一组容器的集合;共享网络;生命周期是短暂的; …

反相器及反相器链的设计

静态特性 1 .开关阈值 2 .噪声容限 3 .稳定性 动态特性 1 .计算电容值 2. 时延分析 3. 从设计角度考虑时延 功耗、能量和能量时延 1.动态功耗 2.静态功耗

Druid监控平台与SpringBoot的actuator、Admin

文章目录 前言Druid监控平台的基础使用actuator基础使用Admin可视化图形监控 前言 Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控,Druid 可以很好的监控 DB 池连接和 SQL 的执行情况…

暑期实习总结(焊点数据管理软件开发):Python操作MySQL数据库、Django搭建前端网页、以及Excel中数据与MySQL数据库的互转

暑期实习总结(焊点数据管理软件开发):Python操作MySQL数据库、Django搭建前端网页、以及Excel中数据与MySQL数据库的互转 ​ 这一周是我在企业实习的最后一周,在企业做的项目已基本完成。这篇博客的目的也是总结一些项目中的一些小问题&…

经典文献阅读之--MobileSAM(比FastSAM更快的SAM框架)

0. 简介 自从MetaAI提出的能够“分割一切”的视觉基础大模型SAM提供了很好的分割效果,为探索视觉大模型提供了一个新的方向。虽然SAM的效果很好,但由于SAM的backbone使用了ViT,导致推理时显存的占用较多,推理速度偏慢&#xff0c…

大数据学习:hive的DQL和DML操作

hive的DQL和DML操作 1. Hive的分桶表 1.1 分桶表原理 分桶是相对分区进行更细粒度的划分 Hive表或分区表可进一步的分桶 分桶将整个数据内容按照某列取hash值,对桶的个数取模的方式决定该条记录存放在哪个桶当中;具有相同hash值的数据进入到同一个文件…

4、监测数据采集物联网应用开发步骤(4)

监测数据采集物联网应用开发步骤(3) 日志或文本文件读写开发 创建全局变量配置代码com.zxy.common.Com_Para.py全局变量根据需要后续补充。 #! python3 # -*- coding: utf-8 -Created on 2023年08月28日 author: zxyong 13738196011#监测数据采集物联网应用--全局变量 impor…

文件名翻译不求人:一键批量翻译,你就是改名专家

文件名翻译不求人:一键批量翻译,你就是改名专家 在日常生活和工作中,我们常常需要处理各种文件,包括文档、图片、视频等。有时候,我们需要对这些文件进行重命名,以便更好地管理和查找。但是,当…

微服务之Nacos

1 版本说明 官网地址: https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 1.1 2021.x 分支 适配 SpringBoot 2.4, Spring Cloud 2021.x 版本及以上的Spring Cloud Alibaba 版本如下表(最新版本用*标记&am…

Android实现监听APP启动、前台和后台

Android 实时监听APP进入前台或后台 前言 在我们开发的过程中,经常会遇到需要我们判断app进入后台,或者切换到前台的情况。比如我们想判断app切换到前台时,显示一个解锁界面,要求用户输入解锁密码才能继续进行操作;我…

pdf怎么转换成jpg图片?这几个方法值得一试

pdf怎么转换成jpg图片?PDF格式的文件在我们的日常生活和工作中十分常见,但有时候我们需要将PDF文件转换成图片格式,以便于在网页上进行展示或者存放到手机相册中。那么,PDF怎么转换成JPG图片呢?下面介绍几种方法。 第一…

Java【手撕滑动窗口】LeetCode 209. “长度最小子数组“, 图文详解思路分析 + 代码

文章目录 前言一、长度最小子数组1, 题目2, 思路分析3, 代码 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: 📕 JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等 📗 Java数据结构: 顺序表, 链…