限流算法学习

文章目录

  • 限流算法
    • 基本介绍
    • 适用场景
      • 计数器算法
      • 滑动窗口算法
      • 令牌桶算法
      • 漏桶算法
      • 综合比较
    • 示例实现

限流算法

限流算法是在系统设计中常用来控制资源访问速率、防止服务过载的技术手段。

基本介绍

主要的限流算法有以下几种:

  1. 计数器算法
    计数器算法是最简单的限流算法,它在一个时间窗口内统计请求次数,如果请求次数超过了设定的阈值,则拒绝服务。这种方法实现简单,但存在时间窗口切换时的瞬间流量突增问题。
  2. 滑动窗口算法
    滑动窗口算法是对计数器算法的改进,它将时间窗口分成多个小的窗口,通过维护这些小窗口的计数,可以更平滑地控制流量。这种算法可以较好地解决计数器算法中存在的突增问题。
  3. 令牌桶算法
    令牌桶算法通过一个固定容量的令牌桶来控制流量,系统以恒定速率往桶中添加令牌,处理请求时需要从桶中取出令牌,如果桶中没有令牌,则拒绝服务。这种算法可以允许一定程度的突发流量,因为桶中可以积累令牌。
  4. 漏桶算法
    漏桶算法将请求放入到一个固定容量的桶中,系统以恒定的速率从桶中取出请求进行处理。如果桶满了,则新进的请求会被丢弃或排队等待。这种算法可以很好地控制数据的平均速率和突发速率。

适用场景

计数器算法

特点:简单直接,通过在固定的时间窗口内计数并限制请求的数量来实现限流。

​ 适用场景:

​ 适用于单一服务实例的场景。

​ 对于那些对流量突增不敏感的简单应用。

​ 局限性:在时间窗口切换的瞬间,可能会允许两倍于阈值的请求通过,导致服务瞬时压力加大。

滑动窗口算法

特点:在计数器算法的基础上改进,将时间窗口划分为多个小窗口,以达到更平滑控制流量的效果。

​ 适用场景:

​ 适合需要更平滑控制请求流量的场景。

​ 当需要减少由于时间窗口切换带来的流量波动时非常有用。

令牌桶算法

特点:通过固定速率添加令牌到桶中,请求需要消耗令牌才能被处理,支持一定程度的突发流量。

​ 适用场景:

​ 适合对突发流量有一定容忍度的场景。

​ 当需要对复杂的分布式系统进行限流,且要求系统能够应对短时间内的高流量压力时。

漏桶算法

特点:以恒定的速率处理请求,可以很好地控制数据的平均速率和突发速率,但超出容量的请求会被丢弃或等待。

​ 适用场景:

​ 适合需要严格控制请求处理速率,保证服务稳定性的场景。

​ 当系统处理能力有硬性限制,不能容忍超过一定速率的请求时。

综合比较

​ 对于简单应用或单实例服务,计数器算法因其实现简单而受到青睐。

​ 滑动窗口算法提供了比计数器更平滑的限流控制,适合对流量波动敏感的应用。

​ 令牌桶算法因其支持一定程度的突发流量而广泛应用于需要灵活处理高低流量变化的分布式系统中。

​ 漏桶算法适合对处理速率有严格要求,需要稳定处理请求的系统。

示例实现

'''计数器算法实现'''
import timeclass RateLimiter:def __init__(self, max_requests, window_size):"""初始化计数器限流器:param max_requests: 时间窗口内的最大请求数:param window_size: 时间窗口大小,单位为秒"""self.max_requests = max_requestsself.window_size = window_sizeself.request_counts = 0self.start_time = time.time()def allow_request(self):"""判断是否允许当前请求:return: 如果允许请求,返回True;否则返回False"""current_time = time.time()# 如果当前时间超出了时间窗口,则重置计数器和开始时间if current_time - self.start_time > self.window_size:self.request_counts = 0self.start_time = current_time# 如果当前请求次数小于最大请求数,则允许请求并增加计数if self.request_counts < self.max_requests:self.request_counts += 1return Trueelse:# 否则,拒绝请求return False# 示例使用
if __name__ == "__main__":limiter = RateLimiter(5, 60)  # 每60秒允许最多5个请求# 模拟请求for i in range(10):time.sleep(1)  # 每秒发送一个请求if limiter.allow_request():print(f"请求{i + 1}: 允许")else:print(f"请求{i + 1}: 被限流")
'''滑动窗口算法实现'''
import time
from collections import dequeclass SlidingWindowLimiter:def __init__(self, max_requests, window_size):"""初始化滑动窗口限流器:param max_requests: 时间窗口内允许的最大请求量:param window_size: 时间窗口大小,单位为秒"""self.max_requests = max_requestsself.window_size = window_sizeself.requests = deque()def allow_request(self):"""判断是否允许当前请求通过:return: 如果允许请求通过,返回True;如果不允许,返回False"""current_time = time.time()# 移除时间窗口之前的请求记录while self.requests and self.requests[0] < current_time - self.window_size:self.requests.popleft()if len(self.requests) < self.max_requests:# 如果当前时间窗口内的请求量小于最大允许请求量,则允许当前请求通过self.requests.append(current_time)return Trueelse:# 否则,拒绝当前请求return False# 示例使用
if __name__ == "__main__":# 创建一个滑动窗口限流器,最大请求量为3,时间窗口为10秒limiter = SlidingWindowLimiter(3, 10)# 模拟请求for _ in range(5):if limiter.allow_request():print("请求通过")else:print("请求被限流")time.sleep(1)
'''令牌桶算法实现'''import time
from threading import Lockclass TokenBucket:def __init__(self, rate, capacity):self._rate = rate  # 每秒往桶里放入令牌的速率self._capacity = capacity  # 桶的容量self._tokens = capacity  # 当前桶内的令牌数量self._last_time = time.time()  # 上次放入令牌的时间self._lock = Lock()  # 线程锁def consume(self, tokens=1):with self._lock:# 计算自上次放入令牌以来应该放入的令牌数量now = time.time()tokens_to_add = (now - self._last_time) * self._rateself._tokens = min(self._capacity, self._tokens + tokens_to_add)self._last_time = now# 检查桶内是否有足够的令牌if tokens <= self._tokens:self._tokens -= tokensreturn Truereturn False# 使用示例
bucket = TokenBucket(5, 10)  # 每秒放入5个令牌,桶容量为10
print(bucket.consume(3))  # 请求3个令牌
print(bucket.consume(7))  # 请求7个令牌
time.sleep(1)
print(bucket.consume(6))  # 经过1秒后,再请求6个令牌
'''漏桶算法实现'''
import time
import threadingclass LeakyBucket:def __init__(self, capacity, leak_rate):"""初始化漏桶算法:param capacity: 桶的容量:param leak_rate: 桶的漏水速率(每秒)"""self.capacity = capacity  # 桶的最大容量self.leak_rate = leak_rate  # 每秒漏水量self.water = 0  # 当前桶内水量(即当前累积的请求量)self.last_leak_time = time.time()  # 上一次漏水时间def allow_request(self, request_units=1):"""判断请求是否可以通过:param request_units: 请求量(默认为1):return: 如果允许请求通过,返回True;否则返回False"""current_time = time.time()# 计算上次漏水后桶内剩余的水量self.water -= (current_time - self.last_leak_time) * self.leak_rateself.water = max(0, self.water)  # 水量不能为负self.last_leak_time = current_timeif self.water + request_units <= self.capacity:# 如果加上当前请求后不会溢出,则允许请求通过self.water += request_unitsreturn Trueelse:# 否则,拒绝请求return False# 示例使用
if __name__ == "__main__":bucket = LeakyBucket(5, 1)  # 容量为5,每秒漏水速率为1def send_requests():for _ in range(10):print(f"请求发送时间: {time.strftime('%X')} - 请求{'通过' if bucket.allow_request() else '被限流'}")time.sleep(0.5)thread = threading.Thread(target=send_requests)thread.start()thread.join()
  for _ in range(10):print(f"请求发送时间: {time.strftime('%X')} - 请求{'通过' if bucket.allow_request() else '被限流'}")time.sleep(0.5)thread = threading.Thread(target=send_requests)
thread.start()
thread.join()

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

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

相关文章

Python语言参考手册 1. 概论

Python语言的精确描述 本专栏致力于提供Python语言的精确描述&#xff0c;包括其语法&#xff08;Syntax&#xff09;、语义&#xff08;Semantics&#xff09;和标准库的详细信息。语法是指编程语言中代码的结构规则&#xff0c;而语义则是指代码的含义&#xff0c;涉及代码如…

解决html2canvas生成图片慢的问题

// 主要看那个点击事件就行 <divclass"textBox-right-board-group"v-for"item in screenList":key"item.id"><!-- 获取不同分辨率下的屏幕的展示的文字大小DPI&#xff1a; fontSize: getFontSize(item.resolutionRatio), --><di…

windows安装 nvm,实现nodejs多版本切换

下载链接&#xff1a;https://github.com/coreybutler/nvm-windows/releases 安装node指定版本 nvm install 版本号 列出所有node版本 nvm ls 切换node版本 nvm use 版本号

AI智能化逐渐趋于成熟后,预测今后最吃香的开发职业

AI智能化正在成熟的路途中&#xff0c;这中间会有波折&#xff0c;但终有一天会来的&#xff0c;我相信等到了这一天&#xff0c;我们的开发效率和代码质量&#xff0c;将会大大不同&#xff0c;而我们的团队与个人&#xff0c;也会面临着很棒的体验。 那么在AI智能化真正趋于成…

前端开发攻略---使用Sass调整颜色亮度,实现Element组件库同款按钮

目录 1、演示 2、实现原理 3、实现代码 1、演示 2、实现原理 改变颜色亮度的原理是通过调整颜色的 RGB 值中的亮度部分来实现的。在 Sass 中&#xff0c;可以使用颜色函数来操作颜色的 RGB 值&#xff0c;从而实现亮度的调整。 具体来说&#xff0c;亮度调整函数通常会改变颜…

武汉星起航:展望跨境电商新篇章,创新发展助力品牌国际化

随着全球经济一体化的深入发展&#xff0c;跨境电商行业正迎来前所未有的发展机遇。在这个充满机遇的时代&#xff0c;武汉星起航电子商务有限公司以其独特的自营亚马逊跨境电商模式和卖家孵化服务&#xff0c;成为了行业内的一股强劲力量。展望未来&#xff0c;武汉星起航将继…

VLM与基础分割模型的联合使用

最近做的项目里有涉及大模型&#xff0c;里面有一部分的功能是&#xff1a; 将图片输入VLM(视觉语言模型&#xff0c;我使用的是llava)&#xff0c;询问图中最显著的物体&#xff0c;将其给出的答案作为基础分割模型&#xff08;我使用的是Grounded-SAM&#xff09;的text prom…

云原生测试实战-云计算大数据云原生架构容器技术Kubernetes计算机软件工程软件开发

系列文章目录 送书第一期 《用户画像&#xff1a;平台构建与业务实践》 送书活动之抽奖工具的打造 《获取博客评论用户抽取幸运中奖者》 送书第二期 《Spring Cloud Alibaba核心技术与实战案例》 送书第三期 《深入浅出Java虚拟机》 送书第四期 《AI时代项目经理成长之道》 …

Gradle报错Cause: zip END header not found,构建问题解决

问题描述 构建报错&#xff1a;Cause: zip END header not found 解决办法 File>>setting>>Build,Execution,Deployment>>Gradle 选择你本地的Gradke路径 问题解决

2024年数维杯数学建模C题思路

文章目录 1 赛题思路2 比赛日期和时间3 竞赛信息4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间&#xff1a;2024…

拼多多投产比怎么逐步调高

提高拼多多的投产比&#xff08;ROI&#xff09;需要综合考虑多个因素&#xff0c;包括点击量、转化率、客单价以及点击花费。以下是一些有效的方法&#xff1a; 拼多多推广可以使用3an推客。3an推客&#xff08;CPS模式&#xff09;给商家提供的营销工具&#xff0c;由商家自…

8-3 html中的表单标签 select和textarea

跟学b站黑马程序员pink老师&#xff0c;之前发过长篇&#xff0c;太长不好阅读&#xff0c;拆分成短篇 8.4.3 select下拉表单元素 如果在页面中有多个选项让用户选择&#xff0c;并且想要节约页面空间&#xff0c;我们可以用<select>标签来定义下拉列表 1.<select&g…

MySQL监控与诊断:从SHOW命令到第三方监控工具

MySQL作为最流行的关系型数据库管理系统之一&#xff0c;其性能和稳定性对于许多应用来说至关重要。为了确保MySQL数据库能够持续、高效地运行&#xff0c;我们需要进行监控和诊断。本文将从MySQL的内置工具&#xff08;如SHOW命令和INFORMATION_SCHEMA&#xff09;出发&#x…

图片批量处理:批量调整图片色调,简单方法与高级技巧

随着数字摄影和社交媒体的普及&#xff0c;我们每天都接触到大量的图片。为了提升图片的观感和视觉效果&#xff0c;对图片进行色调调整变得至关重要。而对于那些需要处理大量图片的用户来说&#xff0c;批量调整图片色调则是一个能够大大提高工作效率的功能。本文将介绍办公提…

layui 数据表格 自动定位新增行位置

由于数据表格新增行后没有到新增到当前位置 继续增加的需求&#xff1a; 因为自己是新增行后到最后一行的 所以 就定位到最后一行 并且 高亮 高亮颜色浅 可自行更改 整理了一下 可根据 情况 修改 // 初始化滚动条位置变量 let tableScroll {scrollTob: 0,scrollLeft: 0,…

【Node.js工程师养成计划】之使用Node连接MongoDB进行增删改查

一、Node连接MongoDB mongodb npm install mongodb # or ... yarn add mongodbdemo: const { MongoClient } require(mongodb); // or as an es module: // import { MongoClient } from mongodb// Connection URL const url mongodb://localhost:27017; const client ne…

大语言模型用到的代码库资源

文章目录 Hugging Face 开源社区DeepSpeedMegatron-LM Hugging Face 开源社区 Hugging Face 是一个致力于推动自然语言处理技术进步的开源社区&#xff0c;专注于为研究人员和工程师提供高效、易用且可重复的自然语言处理技术解决方案。这些解决方案既包括基础的技术流程&#…

PyQt程序的打包

Qt hello - 专注于Qt的技术分享平台 记录下PyQt程序的打包。 一&#xff0c;安装 pip3 install PyInstaller 二&#xff0c;打包 pyinstaller -w -n app app.py 根据需要选择打包参数&#xff0c;例如&#xff1a;-F表示生成单文件模式&#xff0c;即只有一个可执行文件…

【Vue3源码学习】— CH3.5 renderer 详解

renderer 详解 1. 源码解析2. render过程详解2.1 处理 vnode 为 null 的情况2.2 处理 vnode 非 null 的情况2.3 钩子函数的调用2.4 更新 container 的 _vnode 属性:3. 使用示例render 函数是 Vue 的根渲染函数,用于将虚拟节点(VNode)渲染或更新到实际的 DOM 容器中。这个函…

windows驱动开发-内核调度(二)

这篇文档记录剩下的内核调度对象。 信号灯 任何驱动程序都可以使用信号量对象在其驱动程序创建的线程和其他驱动程序例程之间同步操作。 例如&#xff0c;当驱动程序没有未完成的 I/O 请求时&#xff0c;驱动程序专用线程可能会将自身置于等待状态&#xff0c;并且驱动程序的…