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结合API实现即时天气信息
Jan 19 Python
Python获取本机所有网卡ip,掩码和广播地址实例代码
Jan 22 Python
Python cookbook(数据结构与算法)将多个映射合并为单个映射的方法
Apr 19 Python
浅谈tensorflow1.0 池化层(pooling)和全连接层(dense)
Apr 27 Python
Python 访问限制 private public的详细介绍
Oct 16 Python
python实现kmp算法的实例代码
Apr 03 Python
基于python实现的百度音乐下载器python pyqt改进版(附代码)
Aug 05 Python
30秒学会30个超实用Python代码片段【收藏版】
Oct 15 Python
Python3 实现爬取网站下所有URL方式
Jan 16 Python
浅谈Python爬虫原理与数据抓取
Jul 21 Python
Matlab使用Plot函数实现数据动态显示方法总结
Feb 25 Python
Python实现打乒乓小游戏
Sep 25 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 register_shutdown_function函数的深入解析
2013/06/03 PHP
codeigniter自带数据库类使用方法说明
2014/03/25 PHP
PHP生成二维码的两个方法和实例
2014/07/01 PHP
PHP面向对象继承用法详解(优化与减少代码重复)
2016/12/02 PHP
影响jQuery使用的14个方面
2014/09/01 Javascript
JavaScript中的全局对象介绍
2015/01/01 Javascript
javascript insertAfter()定义与用法示例
2016/07/25 Javascript
基于angularjs实现图片放大镜效果
2016/08/31 Javascript
微信小程序 wx:key详细介绍
2016/10/28 Javascript
nodejs中安装ghost出错的原因及解决方法
2017/10/23 NodeJs
nodejs基础之常用工具模块util用法分析
2018/12/26 NodeJs
JavaScript 处理树数据结构的方法示例
2019/06/16 Javascript
关于JS模块化的知识点分享
2019/10/16 Javascript
Javascript中的this,bind和that使用实例
2019/12/05 Javascript
Vue替代marquee标签超出宽度文字横向滚动效果
2019/12/09 Javascript
vue element-ui实现input输入框金额数字添加千分位
2019/12/29 Javascript
Vue获取页面元素的相对位置的方法示例
2020/02/05 Javascript
js+canvas实现五子棋小游戏
2020/08/02 Javascript
antd design table更改某行数据的样式操作
2020/10/31 Javascript
深入理解Python中range和xrange的区别
2017/11/26 Python
python 3.7.0 下pillow安装方法
2018/08/27 Python
Python minidom模块用法示例【DOM写入和解析XML】
2019/03/25 Python
python collections模块的使用
2020/10/16 Python
Toppik顶丰增发纤维官网:解决头发稀疏
2017/12/30 全球购物
UNIONBAY官网:美国青少年服装品牌
2019/03/26 全球购物
海蓝之谜英国官网:La Mer英国
2020/01/15 全球购物
什么是跨站脚本攻击
2014/12/11 面试题
毕业生的自我评价
2013/12/30 职场文书
幸福家庭标语
2014/06/27 职场文书
大学生考试作弊检讨书1000字
2014/10/14 职场文书
党员个人整改方案及措施
2014/10/25 职场文书
总经理岗位职责范本
2015/04/01 职场文书
企业宣传语大全
2015/07/13 职场文书
ajax请求前端跨域问题原因及解决方案
2021/10/16 Javascript
P站美图推荐——变身女主角特辑
2022/03/20 日漫
pt-archiver 主键自增
2022/04/26 MySQL