客户端发送http请求进行流量控制

客户端发送http请求进行流量控制

实现方式 1:使用 Semaphore (信号量) 控制流量

asyncio.Semaphore 是一种简单的流控方法,可以用来限制并发请求数量。

import asyncio
import aiohttp
import timeclass HttpClientWithSemaphore:def __init__(self, max_concurrent_requests=5, request_period=10):self.max_concurrent_requests = max_concurrent_requestsself.request_period = request_periodself.semaphore = asyncio.Semaphore(max_concurrent_requests)self.session = aiohttp.ClientSession()async def fetch(self, url):async with self.semaphore:try:async with self.session.get(url) as response:return await response.text()except Exception as e:print(f"Request failed: {e}")return Noneasync def close(self):await self.session.close()async def main_with_semaphore():client = HttpClientWithSemaphore(max_concurrent_requests=5)urls = ["http://example.com/api/1","http://example.com/api/2","http://example.com/api/3","http://example.com/api/4","http://example.com/api/5","http://example.com/api/6",]tasks = [client.fetch(url) for url in urls]responses = await asyncio.gather(*tasks)for response in responses:if response:print(response)await client.close()if __name__ == "__main__":asyncio.run(main_with_semaphore())

优点

  • 简单易实现,使用内置的 asyncio.Semaphore 就能限制并发请求数量。
  • 易于维护,代码简单清晰。

缺点

  • 缺少精细的流控机制,例如每 10 秒内限制请求数量(只能控制总并发数量)。
  • 难以适应更加复杂的流控需求。

实现方式 2:使用滑动窗口 (Sliding Window) 算法

滑动窗口算法是一种可以精确控制在一定时间内的请求数量的机制。它能平滑地调整速率。

import asyncio
import aiohttp
from collections import deque
import timeclass SlidingWindowRateLimiter:def __init__(self, max_requests, window_seconds):self.max_requests = max_requestsself.window_seconds = window_secondsself.timestamps = deque()async def acquire(self):current_time = time.monotonic()# 清理超出窗口时间的旧请求while self.timestamps and current_time - self.timestamps[0] > self.window_seconds:self.timestamps.popleft()if len(self.timestamps) < self.max_requests:self.timestamps.append(current_time)return Trueelse:# 计算需要等待的时间sleep_time = self.window_seconds - (current_time - self.timestamps[0])await asyncio.sleep(sleep_time)return await self.acquire()class HttpClientWithSlidingWindow:def __init__(self, max_requests_per_period=5, period=10):self.rate_limiter = SlidingWindowRateLimiter(max_requests_per_period, period)self.session = aiohttp.ClientSession()async def fetch(self, url):await self.rate_limiter.acquire()try:async with self.session.get(url) as response:return await response.text()except Exception as e:print(f"Request failed: {e}")return Noneasync def close(self):await self.session.close()async def main_with_sliding_window():client = HttpClientWithSlidingWindow(max_requests_per_period=5, period=10)urls = ["http://example.com/api/1","http://example.com/api/2","http://example.com/api/3","http://example.com/api/4","http://example.com/api/5","http://example.com/api/6",]tasks = [client.fetch(url) for url in urls]responses = await asyncio.gather(*tasks)for response in responses:if response:print(response)await client.close()if __name__ == "__main__":asyncio.run(main_with_sliding_window())

优点

  • 更加精确地控制时间窗口内的请求数量。
  • 平滑控制请求速率,适用于需要稳定流量的情况。

缺点

  • 实现稍复杂,需要维护一个请求时间戳队列。
  • 在极端条件下,如果有大量请求积压,可能会造成延迟波动。

实现方式 3:使用 aiolimiter 第三方库

aiolimiter 是一个专门用于异步流控的 Python 库,支持令牌桶和滑动窗口算法。

安装 aiolimiter

pip install aiolimiter

代码示例

import asyncio
import aiohttp
from aiolimiter import AsyncLimiterclass HttpClientWithAiolimiter:def __init__(self, max_requests_per_period=5, period=10):# 初始化流控器,每10秒允许5个请求self.limiter = AsyncLimiter(max_requests_per_period, period)self.session = aiohttp.ClientSession()async def fetch(self, url):async with self.limiter:try:async with self.session.get(url) as response:return await response.text()except Exception as e:print(f"Request failed: {e}")return Noneasync def close(self):await self.session.close()async def main_with_aiolimiter():client = HttpClientWithAiolimiter(max_requests_per_period=5, period=10)urls = ["http://example.com/api/1","http://example.com/api/2","http://example.com/api/3","http://example.com/api/4","http://example.com/api/5","http://example.com/api/6",]tasks = [client.fetch(url) for url in urls]responses = await asyncio.gather(*tasks)for response in responses:if response:print(response)await client.close()if __name__ == "__main__":asyncio.run(main_with_aiolimiter())

优点

  • 使用方便,aiolimiter 直接支持流控机制。
  • 代码简洁且配置灵活,可直接设置流控参数。
  • 第三方库已经过优化,适合快速开发。

缺点

  • 依赖于外部库,需要额外安装。
  • 灵活性相对有限,无法完全控制算法的细节。

比较总结

实现方式优点缺点适用场景
信号量控制 (Semaphore)简单易实现,易于维护控制粒度较粗,不适合复杂流控适合简单并发控制场景
滑动窗口 (Sliding Window)精确控制时间窗口内的请求数量,平滑控制请求速率实现稍复杂,可能出现延迟波动适合需要精确流控的场景
aiolimiter 第三方库使用方便,代码简洁,库优化良好依赖外部库,灵活性相对有限适合快速实现流控的项目

希望这些不同的实现方式和比较能够帮助你选择适合的 HTTP 客户端实现方案。如果你对某种实现方式有特别的需求或疑问,请随时告知!

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

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

相关文章

Java Web 工程全貌

通过下图&#xff0c;我们可以一览 Java Web 工程的全貌 通过上图&#xff0c;我们能够基本窥探整个 Java Web 工程的面貌&#xff0c;包括前端&#xff0c;后端&#xff0c;甚至是运维。 接下来&#xff0c;我们就结合文字描述&#xff0c;加深理解。 部署Vue前端和Spring…

Linux入门:环境变量与进程地址空间

一. 环境变量 1. 概念 1️⃣基本概念&#xff1a; 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪里&#x…

Redis数据结构及实现

目录 1. Redis与数据结构简介2. Redis五种数据结构详解3. Python面向对象实现Redis数据结构1. String结构2. List结构3. Set结构4. SortedSet结构5. Hash结构 4. 数据结构应用案例及代码实现案例 1&#xff1a;使用Redis String实现计数器案例 2&#xff1a;使用Redis List实现…

【优选算法 — 滑动窗口】水果成篮 找到字符串中所有字母异位词

水果成篮 水果成篮 题目描述 因为只有两个篮子&#xff0c;每个篮子装的水果种类相同&#xff0c;如果从 0 开始摘&#xff0c;则只能摘 0 和 1 两个种类 &#xff1b; 因为当我们在两个果篮都装有水果的情况下&#xff0c;如果再走到下一颗果树&#xff0c;果树的水果种类…

Java 中使用Mockito 模拟对象的单元测试的快速示例

Mockito是一个流行的Java模拟框架&#xff0c;它允许你在单元测试中创建和配置模拟对象&#xff0c;以便在测试过程中替换那些不容易构造或获取的对象。 Mockito可以与JUnit无缝集成&#xff0c;下面的示例演示 Mockito JUnit实现模拟对象的单元测试。 依赖导入 这里使用Mav…

STM32 创建一个工程文件(寄存器、标准库)

首先到官网下载对应型号的固件包&#xff1a; 像我的STM32F103C8T6的就下载这个&#xff1a; 依次打开&#xff1a; .\STM32F10x_StdPeriph_Lib_V3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm 可以看到&#xff1a; 这…

vue-h5:在h5中实现相机拍照加上身份证人相框和国徽框

方案1&#xff1a;排出来照片太糊了&#xff0c;效果不好 1.基础功能 参考&#xff1a; https://blog.csdn.net/weixin_45148022/article/details/135696629 https://juejin.cn/post/7327353533618978842?searchId20241101133433B2BB37A081FD6A02DA60 https://www.freesio…

论文精读(笔记)

———李沐老师论文精度视频笔记 一、论文结构 1.title&#xff1a;标题 2.abstract&#xff1a;摘要 3.instruction&#xff1a;介绍&#xff08;导言&#xff09; 4.method&#xff1a;你提出的算法 5.experiment&#xff1a;实验证明算法可行 6.conclusion&#xff1a;结论…

初识GIS

文章目录 一、什么叫地理信息1、定义2、主要特点3、分类 二、什么叫GIS1、定义2、GIS对空间信息的储存2.1、矢量数据模型2.2、栅格数据模型 3、离散栅格和连续栅格的区别 三、坐标系统1、为什么要存在坐标系统&#xff1f;2、地理坐标系2.1、定义与特点2.2、分类 3、投影坐标系…

Android 开发指南:初学者入门

Android 是全球最受欢迎的移动操作系统之一&#xff0c;为开发者提供了丰富的工具和资源来创建各种类型的应用程序。本文将为你提供一个全面的入门指南&#xff0c;帮助你从零开始学习 Android 开发。 目录 1. 了解 Android 平台[1]2. 设置开发环境[2]3. 学习基础知识[3]4. 创…

表的数据结构和常见操作

在计算机科学中&#xff0c;表数据结构是一种用于组织和存储数据的方式&#xff0c;它具有行和列的形式&#xff0c;类似于电子表格或数据库表。表数据结构可以用于多种用途&#xff0c;具体取决于实现和使用场景。以下是几种常见的表数据结构&#xff1a; ### 1. 数组&#x…

【QML】QML多线程应用(WorkerScript)

1. 实现功能 QML项目中&#xff0c;点击一个按键后&#xff0c;运行一段比较耗时的程序&#xff0c;此时ui线程会卡住。如何避免ui线程卡住。 2. 单线程&#xff08;会卡住&#xff09; 2.1 界面 2.2 现象 点击delay btn后&#xff0c;执行耗时函数&#xff08;TestJs.func…

MFC1(note)

引言 在学习SDK后我们发现&#xff0c;写消息好麻烦&#xff0c;处理消息更麻烦 处理消息效率低发送消息效率低 所以把SDK中这些消息全部封装好 MFC封装了windows 的大部分API 这里说一下QT架构跨平台 MFC用得如何取决于你SDK的水平 创建 如果打开没有MFC 一般勾选以下…

封装一个省市区的筛选组件

筛选功能&#xff1a;只能单选&#xff08;如需多选需要添加show-checkbox多选框属性&#xff09;&#xff0c;选中省传递省的ID&#xff0c;选中市传递省、市的ID&#xff0c; 选中区传递省市区的ID 父组件&#xff1a; <el-form-item><div style"width: 240px;…

Java 包装类

在Java中&#xff0c;包装类是面向对象编程中的一个基本概念。 它们通过将基本数据类型转换为对象&#xff0c;搭建了两个世界之间的桥梁。 本文将从头到尾全面介绍什么是包装类、它们在Java编程中的重要性、工作原理以及使用它们的优缺点。 读完这篇文章后&#xff0c;您将…

DOCKER 镜像基础命令

目录 1. 查看镜像列表 2. 拉取镜像 3. 推送镜像到仓库 4. 保存镜像到文件 5. 导出镜像并压缩 6. 加载镜像文件 7. 标记镜像&#xff08;重命名&#xff09; 8. 检查镜像信息 9. 构建新镜像 10. 删除镜像 11. 清除dangling和不再使用的镜像 12. 将一台主机的所有镜像…

大模型在蓝鲸运维体系应用——蓝鲸运维开发智能助手

本文来自腾讯蓝鲸智云社区用户: CanWay 背景 1、运维转型背景 蓝鲸平台从诞生之初&#xff0c;就一直在不遗余力地推动运维转型&#xff0c;让运维团队可以通过一体化PaaS平台&#xff0c;快速编写脚本&#xff0c;编排流程&#xff0c;开发运维工具&#xff0c;从被动地提供…

独家|京东上线自营秒送,拿出二十年底牌和美团竞争

京东自营秒送开启招商&#xff0c;即时零售也要全托管&#xff1f; 作者|王迟 编辑|杨舟 据「市象」独家获悉&#xff0c;京东将在近期上线自营秒送业务&#xff0c;目前已经开始邀约制招商。「市象」获得的招商资料显示&#xff0c;和5月刚升级上线的京东秒送以POP模式不同&…

GEE 数据集——美国gNATSGO(网格化国家土壤调查地理数据库)完整覆盖了美国所有地区和岛屿领土的最佳可用土壤信息

目录 简介 代码 引用 网址推荐 知识星球 机器学习 gNATSGO&#xff08;网格化国家土壤调查地理数据库&#xff09; 简介 gNATSGO&#xff08;网格化国家土壤调查地理数据库&#xff09;数据库是一个综合数据库&#xff0c;完整覆盖了美国所有地区和岛屿领土的最佳可用土…

JavaSE常用API-日期(计算两个日期时间差-高考倒计时)

计算两个日期时间差&#xff08;高考倒计时&#xff09; JDK8之前日期、时间 Date SimpleDateFormat Calender JDK8开始日期、时间 LocalDate/LocalTime/LocalDateTime ZoneId/ZoneDateTIme Instant-时间毫秒值 DateTimeFormatter Duration/Period