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中函数eval和ast.literal_eval的区别详解
Aug 10 Python
TF-IDF算法解析与Python实现方法详解
Nov 16 Python
Python编程pygal绘图实例之XY线
Dec 09 Python
Python打印“菱形”星号代码方法
Feb 05 Python
TensorFlow模型保存和提取的方法
Mar 08 Python
Python元组拆包和具名元组解析实例详解
Mar 26 Python
python获取命令行输入参数列表的实例代码
Jun 23 Python
python单线程文件传输的实例(C/S)
Feb 13 Python
python实现两个经纬度点之间的距离和方位角的方法
Jul 05 Python
Django配置MySQL数据库的完整步骤
Sep 07 Python
python 项目目录结构设置
Feb 14 Python
Python基础之常用库常用方法整理
Apr 30 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
PHP session会话的安全性分析
2011/09/08 PHP
PHP+Mysql+jQuery实现动态展示信息
2011/10/08 PHP
js 实现无缝滚动 兼容IE和FF
2009/07/15 Javascript
javascript中判断一个值是否在数组中并没有直接使用
2012/12/17 Javascript
jQuery仿gmail实现fixed布局的方法
2015/05/27 Javascript
浅析jQuery Mobile的初始化事件
2015/12/03 Javascript
jQuery Uploadify 上传插件出现Http Error 302 错误的解决办法
2015/12/12 Javascript
第一次接触神奇的Bootstrap网格系统
2016/07/27 Javascript
Bootstrap如何创建表单
2016/10/21 Javascript
简单实现JavaScript图片切换效果
2016/11/28 Javascript
使用store来优化React组件的方法
2017/10/23 Javascript
vue.js提交按钮时进行简单的if判断表达式详解
2018/08/08 Javascript
webpack css加载和图片加载的方法示例
2018/09/11 Javascript
node express使用HTML模板的方法示例
2019/08/22 Javascript
vant-ui组件调用Dialog弹窗异步关闭操作
2020/11/04 Javascript
解决iView Table组件宽度只变大不变小的问题
2020/11/13 Javascript
[55:23]VGJ.T vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
python合并文本文件示例
2014/02/07 Python
教你学会使用Python正则表达式
2017/09/07 Python
python常用库之NumPy和sklearn入门
2019/07/11 Python
python实现一行输入多个值和一行输出多个值的例子
2019/07/16 Python
Pandas之groupby( )用法笔记小结
2019/07/23 Python
使用Tensorboard工具查看Loss损失率
2020/02/15 Python
Python定义一个函数的方法
2020/06/15 Python
15个Pythonic的代码示例(值得收藏)
2020/10/29 Python
10分钟理解CSS3 FlexBox弹性布局
2018/12/20 HTML / CSS
HTML5 Canvas的性能提高技巧经验分享
2013/07/02 HTML / CSS
详解HTML5将footer置于页面最底部的方法(CSS+JS)
2018/10/11 HTML / CSS
英国领先的餐饮折扣俱乐部:Gourmet Society
2020/07/26 全球购物
华为python面试题
2016/05/03 面试题
应届优秀本科大学毕业生自我鉴定
2014/01/21 职场文书
政治思想表现评语
2014/05/04 职场文书
党的群众路线教育实践活动个人承诺书
2014/05/22 职场文书
三严三实对照检查材料
2014/09/22 职场文书
《日月潭》教学反思
2016/02/20 职场文书
Python自动操作神器PyAutoGUI的使用教程
2022/06/16 Python