Python并发请求下限制QPS(每秒查询率)的实现代码


Posted in Python onJune 05, 2020

  前两天有一个需求,需要访问某API服务器请求数据,该服务器限制了QPS=2(哈哈应该都知道是哪个服务器了吧_(:з」∠)_),因为QPS很小所以就使用阻塞式请求。后来开通了服务,QPS提高到了20,阻塞式请求满足不了这个QPS了,于是使用了GRequests来并发请求数据,但这里又遇到了一个问题:并发太快,服务器通过发送错误码拒绝了很多数据的响应,造成了资源的浪费。
  故在此记录以下几种 节流(Throttle) 方法:

  以下均假设有如下包和数据前提:

import grequests

urls = [
 "https://www.baidu.com",
 "https://www.google.com"
]
requests = [
 grequests.get(url)
 for url in urls
] * 1000

rate = 20 # 表示 20 请求/秒

time.sleep(1)

  这是最简单的方法,通过time.sleep(1)阻塞进程来控制每秒并发数量。用公式表达如下:Time=++time.sleep(1)Time = 请求准备时延 + 请求发送时延 + time.sleep(1)Time=请求准备时延+请求发送时延+time.sleep(1)   但是这种方法有一个较小的问题:不精确 。数据量越大,方差越大。

from time import sleep

req_groups = [
 requests[i: i+rate]
 for i in range(0, len(requests), rate)
]

ret = []
for req_group in req_groups:
 ret += grequests.map(req_group)
 sleep(1)

print(ret)

令牌桶(token bucket)方法

  这种方法较精确,可以确保误差不超过±1(当然前提是你的电脑和目标服务器都能承受的了高并发)。以下是耗时的公式表示:Time=++延Time = 请求准备时延 + 请求发送时延 + 令牌桶阻塞时延Time=请求准备时延+请求发送时延+令牌桶阻塞时延 1+延令牌桶阻塞时延 ≈ 1 - 请求准备时延 + 请求发送时延令牌桶阻塞时延≈1−请求准备时延+请求发送时延   这种方法当然也有一点缺陷,CPU看起来会很高(这是由于 while pass),尽管CPU真实使用率很低。

from time import time

class Throttle:
 def __init__(self, rate):
  self.rate = rate
  self.tokens = 0
  self.last = 0
 
 def consume(self, amount=1):
  now = time()
  
  if self.last == 0:
   self.last = now
  
  elapsed = now - self.last

  if int(elapsed * self.rate):
   self.tokens += int(elapsed * self.rate)
   self.last = now
  
  self.tokens = (
   self.rate
   if self.tokens > self.rate
   else self.tokens
  )
  
  if self.tokens >= amount:
   self.tokens -= amount
  else:
   amount = 0
  
  return amount

throttle = Throttle(rate)

req_groups = [
 requests[i: i+rate]
 for i in range(0, len(requests), rate)
]

ret = []
for req_group in req_groups:
 ret += grequests.map(req_group)
 while throttle.consume():
  pass # 阻塞

print(ret)

GRequests-Throttle

  这是一个使用令牌桶(token bucket)方法进行封装的GRequests修改版,使用方法很简单:
  首先安装grequests-throttle(清华镜像源更新较慢,推荐使用阿里镜像源)

pip install grequests-throttle
import grequests_throttle as gt

ret = gt.map(requests, rate=rate)
print(ret)

总结

  如果并发请求数量较小,可以考虑使用time.sleep(1)简单快捷;当并发请求数量较大时,使用令牌桶(token bucket)方法能最大化利用每一秒;如果不想写太多代码,可以使用GRequests-Throttle包进行请求流量控制。

到此这篇关于Python并发请求下限制QPS(每秒查询率)实现的文章就介绍到这了,更多相关Python并发请求下限制QPS(每秒查询率)实现内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python性能优化的20条建议
Oct 25 Python
自动化Nginx服务器的反向代理的配置方法
Jun 28 Python
Python使用PDFMiner解析PDF代码实例
Mar 27 Python
详解Python pygame安装过程笔记
Jun 05 Python
Python实现字符串匹配算法代码示例
Dec 05 Python
详解Python安装scrapy的正确姿势
Jun 26 Python
Python常见排序操作示例【字典、列表、指定元素等】
Aug 15 Python
python查看模块,对象的函数方法
Oct 16 Python
PyQt5 界面显示无响应的实现
Mar 26 Python
如何用python识别滑块验证码中的缺口
Apr 01 Python
基于PyQt5制作一个群发邮件工具
Apr 08 Python
python开发制作好看的时钟效果
May 02 Python
Python爬虫爬取百度搜索内容代码实例
Jun 05 #Python
python3读取autocad图形文件.py实例
Jun 05 #Python
Python实现加密接口测试方法步骤详解
Jun 05 #Python
基于python 将列表作为参数传入函数时的测试与理解
Jun 05 #Python
python 引用传递和值传递详解(实参,形参)
Jun 05 #Python
Python检测端口IP字符串是否合法
Jun 05 #Python
Python如何基于Tesseract实现识别文字功能
Jun 05 #Python
You might like
SONY ICF-F10中波修复记
2021/03/02 无线电
php打造属于自己的MVC框架
2012/03/07 PHP
Laravel-admin之修改操作日志的方法
2019/09/30 PHP
谈谈关于JavaScript 中的 MVC 模式
2013/04/11 Javascript
JavaScript匿名函数与委托使用示例
2014/07/22 Javascript
javascript定义类和类的实现实例详解
2015/12/01 Javascript
Vuejs 组件——props数据传递的实例代码
2017/03/07 Javascript
详解vue与后端数据交互(ajax):vue-resource
2017/03/16 Javascript
js实现鼠标移动到图片产生遮罩效果
2017/10/21 Javascript
JavaScript中严格判断NaN的方法
2018/02/16 Javascript
koa2实现登录注册功能的示例代码
2018/12/03 Javascript
vue项目搭建以及全家桶的使用详细教程(小结)
2018/12/19 Javascript
详解Vue-cli3 项目在安卓低版本系统和IE上白屏问题解决
2019/04/14 Javascript
[27:53]2014 DOTA2华西杯精英邀请赛 5 24 NewBee VS iG
2014/05/26 DOTA
[57:29]Alliance vs KG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/17 DOTA
python标准日志模块logging的使用方法
2013/11/01 Python
基于Python实现通过微信搜索功能查看谁把你删除了
2016/01/27 Python
200行自定义python异步非阻塞Web框架
2017/03/15 Python
python用户评论标签匹配的解决方法
2018/05/31 Python
python创建文件时去掉非法字符的方法
2018/10/31 Python
python实现三次样条插值
2018/12/17 Python
pyQt5实时刷新界面的示例
2019/06/25 Python
python修改文件内容的3种方法详解
2019/11/15 Python
opencv3/C++图像像素操作详解
2019/12/10 Python
keras 自定义loss损失函数,sample在loss上的加权和metric详解
2020/05/23 Python
python 制作简单的音乐播放器
2020/11/25 Python
HTML5中的拖放实现详解
2017/08/23 HTML / CSS
John Hardy官方网站:手工设计首饰的奢侈品牌
2017/07/05 全球购物
毕业生简单求职信
2013/11/19 职场文书
动物科学专业毕业生的自我评价
2013/11/29 职场文书
天网工程实施方案
2014/03/26 职场文书
小学校园文化建设汇报材料
2014/08/19 职场文书
建设办主任四风问题整改思路和措施
2014/09/20 职场文书
机械专业毕业生自我鉴定2014
2014/10/04 职场文书
党员三严三实对照检查材料
2014/10/13 职场文书
如何用JS实现网页瀑布流布局
2021/04/24 Javascript