客户端发送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请求进行流量控制
客户端发送http请求进行流量控制 实现方式 1:使用 Semaphore (信号量) 控制流量 asyncio.Semaphore 是一种简单的流控方法,可以用来限制并发请求数量。 import asyncio import aiohttp import timeclass HttpClientWithSemaphore:def __init__(self, …...

STM32 低功耗模式详解
目录 一、什么是低功耗 二、低功耗的核心思想 三、STM32的3种低功耗模式 1、睡眠模式 (Sleep Mode) 2、停止模式 (Stop Mode) 3、 待机模式 (Standby Mode) 四、相关电源管理寄存器 1、PWR_CR (Power Control Register, 电源控制寄存器) 2、PWR_CSR (Power Control/St…...

我的第一个PyQt5程序
PyQt5的开发环境配置完成之后,开始编写第一个PyQt5的程序。 方法一:使用将.ui转换成.py文件的方法 import sys from FirstPyQt import Ui_MainWindow from PyQt5.QtWidgets import *#QtCore,QtGui,QtWidgets # from QtTest import Ui_MainWindow#导入Q…...

Unity调用Python
代码如下: if (useAI){/** 通过PaddlePaddle进行合成处理* */// 创建线程参数对象ThreadParameters parameters new ThreadParameters(){pythonPath "python", // 如果 Python 在系统路径中,可以直接使用 "python"pythonScript U…...

前端,location.reload刷新页面
location.reload() 是 JavaScript 中的一个方法,它用于重新加载当前页面。当你调用这个方法时,浏览器会重新加载当前页面的资源,就像用户点击了浏览器的刷新按钮一样。 基本用法 // 刷新当前页面 location.reload();带参数的用法 location…...

5G的发展演进
5G发展的驱动力 什么是5G [远程会议,2020年7月10日] 在来自世界各地的政府主管部门、电信制造及运营企业、研究机构约200多名会议代表和专家们的共同见证下,ITU-R WP 5D#35e远程会议宣布3GPP 5G技术(含NB-IoT)满足IMT-2020 5G技…...

数据库参数备份
MySQL #!/bin/bash # 获取当前日期和时间的时间戳 TIMESTAMP$(date "%Y%m%d-%H%M%S")# 0、创建目录 mkdir /tmp/parameter_$TIMESTAMP/# 1、获取所有命名空间 echo "1、获取所有命名空间" NAMESPACES$(kubectl get ns | grep qfusion- | grep -v qfusion-…...

PG数据库 数据库时间字段 开始时间和结束时间,判断和查询条件的开始和截止时间存在交集,SQL如何编写
PG 数据库时间字段 开始时间和结束时间,判断和查询条件的开始和截止时间存在交集,SQL如何编写? 在 PostgreSQL 中,如果你想要查询那些时间段(由 开始时间 和 结束时间 定义)与给定的时间段有交集的记录&am…...

k8s服务内容滚动升级以及常用命令介绍
查看K8S集群所有的节点信息 kubectl get nodes 删除K8S集群中某个特定节点 kubectl delete nodes/10.0.0.123 获取K8S集群命名空间 kubectl get namespace 获取K8S所有命名空间的那些部署 kubectl get deployment --all-namespaces 创建命名空间 web界面上看到的效果,但是…...

机器学习: LightGBM模型(优化版)——高效且强大的树形模型
LightGBM(Light Gradient Boosting Machine)是一种基于梯度提升决策树(GBDT)的框架,由微软提出。它具有高效的训练速度、低内存占用、支持并行和GPU加速等特点,非常适合大规模数据的训练任务,尤…...

Wordpress常用配置,包括看板娘跨域等
一个Wordpress的博客已经搭建完成了,那么为了让它看起来更有人间烟火气一点,有一些常用的初始配置,这里整理一下。 修改页脚 页脚这里默认会显示Powered by Wordpress,还有一个原因是这里要加上备案信息。在主题里找到页脚&…...

Python学习从0到1 day27 Python 高阶技巧 ③ 设计模式 — 单例模式
此去经年,再难同游 —— 24.11.11 一、什么是设计模式 设计模式是一种编程套路,可以极大的方便程序的开发最常见、最经典的设计模式,就是我们所学习的面向对象了。 除了面向对象外,在编程中也有很多既定的套路可以方便开发,我们称之为设计模…...

Unity 网格模型及优化
一个模型中可以包含很多网格,一个模型可以由多个网格组成。在Unity3D中一个网格可以由多个子网格(Sub-Mesh)组成。 在渲染引擎的时候,每个子网格都要匹配一个材质球来做渲染,实际上一个子网格本身就是一个个普通的模型࿰…...

离线 快速搭建 docker docker-compose k8s 环境
所需资源 sealos_5.0.1_linux_arm64.tar.gzkubernetes.tar等docker-compose-linux-aarch64 离线安装sealos,用于安装k8sdocker 首先安装sealos工具 tar zxvf sealos_5.0.1_linux_arm64.tar.gz sealos && chmod x sealos && mv sealos /usr/bin*…...

Excel根据条件动态索引单元格范围
假如我是一个老板,下面有数不胜数的员工,我要检查他们每周的工作产出,列一个排行榜,提高员工积极性,毕竟多劳多得嘛。 每天去手动统计,未免显得不太聪明,我们可以利用公式来解决这个问题。 我们…...

【计算机网络五】HTTP协议!网站运行的奥秘!
目录 HTTP协议 1.HTTP是什么? 2.Fiddler抓包查看HTTP协议格式 3.HTTP请求 4.HTTP响应 HTTP协议 1.HTTP是什么? HTTP ( 全称为 " 超文本传输协议 ") 诞生与 1991 年 . 目前已经发展为最主流使用的一种应用层协议 . HTTP 的前几个版本…...

开源模型应用落地-qwen模型小试-Qwen2.5-7B-Instruct-tool usage入门-Qwen-Agent深入学习(四)
一、前言 Qwen-Agent 是一个利用开源语言模型Qwen的工具使用、规划和记忆功能的框架。其模块化设计允许开发人员创建具有特定功能的定制代理,为各种应用程序提供了坚实的基础。同时,开发者可以利用 Qwen-Agent 的原子组件构建智能代理,以理解和响应用户查询。 本篇将换一种方…...

stream学习
Stream流 定义 Steam流,用于操作集合或者数组中的数据,大量结合了Lamda表达式的语法风格,代码简洁。 重点: 流只能收集一次 获取Stream流 Stream流要与数据源建立连接。 1.list 直接调用steam()即可 // list List<Stri…...

【数据结构】实验二 单链表的基本操作
一、实验目的 掌握线性表的链式存储结构的表示和实现方法。 掌握链表基本操作的算法实现,以及对相应算法的性能分析。 二、实验内容 1)根据输入的一系列整数,以0标志结束,用头插法建立单链表,并输出单链表中各元素…...

SQL 分组查询中的非聚合列要求及实例解析
在 SQL 查询中,当我们对数据进行分组时,通常会用到 GROUP BY 子句。SQL 标准要求:所有非聚合列(即没有使用聚合函数的列)都必须出现在 GROUP BY 子句中,或者是聚合函数的结果。这篇文章通过一个实例来说明这…...

Unity中实现战斗帧同步的高级技术
一、帧同步的基本原理 帧同步(Frame Synchronization)在网络游戏中指的是在每一帧上保证所有玩家所看到的游戏状态一致,而不是每个玩家单独计算自己的状态。实现帧同步通常需要每个客户端仅发送用户输入到服务器,并由服务器进行全…...

Qt 正则表达式提取文件中的 USB 设备 ID
Qt 正则表达式提取文件中的 USB 设备 ID flyfish 文档内容 Bus: 001 Device: 001 Description: 1d6b:0002 Linux Foundation 2.0 root hub Bus: 002 Device: 003 Description: 0e0f:0002 , Inc. USB Hub Bus: 002 Device: 002 Description: 0e0f:0003 , Inc. Mouse Bus: 002…...

使用 Python 和 OpenCV 实现摄像头人脸检测并截图
概述 在现代应用中,人脸检测是一项非常重要的技术,广泛应用于安全监控、身份验证等领域。本文将详细介绍如何使用 Python 和 OpenCV 库实现摄像头人脸检测并截图,并通过具体的代码示例来展示整个过程。 环境准备 在开始编写代码之前&#…...

【二叉搜素树】——LeetCode二叉树问题集锦:6个实用题目和解题思路
文章目录 计算布尔二叉树的值求根节点到叶节点的数字之和二叉树剪枝验证二叉搜索树二叉搜索树中第K小的元素二叉树的所有路径 计算布尔二叉树的值 解题思路: 这是一个二叉树的布尔评估问题。树的每个节点包含一个值,其中叶子节点值为 0 或 1࿰…...
【计算机视觉】FusionGAN
1. FusionGAN论文阅读 abreheret/FusionGAN: Pytorch implementation of "Generating a Fusion Image: One’s Identity and Another’s Shape" 1.1. WHY 在现实世界中,将对象或人物转换为期望的形状是一种常用技术,但现有的图像翻译方法在处理身份和形状时存在…...

问:SQL优化,七条实践总结?
SQL语句优化是数据库性能调优的重要部分,通过合理的优化可以显著提升查询速度和系统性能。文章总结几种常见SQL语句优化方法。 1. 优化Where子句的顺序 原则:表之间的连接条件应写在其他Where条件之前,能够过滤掉最大数量记录的条件应优先写…...

unity单例模式的不同声明(待完善
总结: 这段代码实现了一个泛型单例模式(Singleton Pattern),用于确保某个类(由泛型参数 T 指定)在整个应用程序中只有一个实例,并且在第一次访问时才创建该实例。该模式保证了该实例的全局唯一…...

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

vue2,vue3响应式的理解
vue2的话主要使用的是defineProperty对已有属性添加get,set,从而完成对数据的响应式控制,但每次需要for循环对属性进行遍历 function DefineReactive(target, key, value) {//存在多层嵌套的objectObserver(value);Object.defineReactive(target, key, {get() {retu…...

群控系统服务端开发模式-应用开发-前端退出功能
我们从未登录一直到退出,现在已经登录到操作,现在完成退出。退出有两种情况下会退出:第一种情况下是手动点击退出按钮,第二种情况下是登录过期时间到了自动退出的。 一、手动退出 因退出及个人信息页面都在公有页面,所…...