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计算最小优先级队列代码分享
Dec 18 Python
Python冒泡排序注意要点实例详解
Sep 09 Python
python方法生成txt标签文件的实例代码
May 10 Python
Python爬虫的两套解析方法和四种爬虫实现过程
Jul 20 Python
Django如何自定义分页
Sep 25 Python
python中正则表达式与模式匹配
May 07 Python
Python通用函数实现数组计算的方法
Jun 13 Python
Python进阶:生成器 懒人版本的迭代器详解
Jun 29 Python
Python使用pyexecjs代码案例解析
Jul 13 Python
Python使用Selenium模拟浏览器自动操作功能
Sep 08 Python
python爬虫筛选工作实例讲解
Nov 23 Python
matplotlib运行时配置(Runtime Configuration,rc)参数rcParams解析
Jan 05 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 mysql_real_escape_string函数用法与实例教程
2013/09/30 PHP
php使用ffmpeg向视频中添加文字字幕的实现方法
2016/05/23 PHP
Prototype Hash对象 学习
2009/07/19 Javascript
解析Javascript中难以理解的11个问题
2013/12/09 Javascript
基于dropdown.js实现的两款美观大气的二级导航菜单
2015/09/02 Javascript
vue2.0+webpack环境的构造过程
2016/11/08 Javascript
JS中判断null的方法分析
2016/11/21 Javascript
javascript简单进制转换实现方法
2016/11/24 Javascript
Vue项目中设置背景图片方法
2018/02/21 Javascript
vue前后分离调起微信支付
2019/07/29 Javascript
swiper4实现移动端导航切换
2020/10/16 Javascript
jQuery 常用特效实例小结【显示与隐藏、淡入淡出、滑动、动画等】
2020/05/19 jQuery
Nodejs 数组的队列以及forEach的应用详解
2021/02/25 NodeJs
Python ORM框架SQLAlchemy学习笔记之安装和简单查询实例
2014/06/10 Python
跟老齐学Python之关于循环的小伎俩
2014/10/02 Python
python实现rsa加密实例详解
2017/07/19 Python
使用TensorFlow实现SVM
2018/09/06 Python
使用Python处理BAM的方法
2018/09/28 Python
使用numba对Python运算加速的方法
2018/10/15 Python
python实现简单加密解密机制
2019/03/19 Python
Python使用Opencv实现图像特征检测与匹配的方法
2019/10/30 Python
MATLAB数学建模之画图汇总
2020/07/16 Python
python中PyQuery库用法分享
2021/01/15 Python
美国从事品牌鞋类零售的连锁店:Famous Footwear
2016/08/25 全球购物
法国综合购物网站:RueDuCommerce
2016/09/12 全球购物
Europcar澳大利亚官网:全球汽车租赁领域的领导者
2019/03/24 全球购物
《月迹》教学反思
2014/02/19 职场文书
假面舞会策划方案
2014/05/29 职场文书
小学教师师德师风演讲稿
2014/08/22 职场文书
团委副书记工作总结
2015/08/14 职场文书
Mysql Online DDL的使用详解
2021/05/20 MySQL
Pandas加速代码之避免使用for循环
2021/05/30 Python
python迷宫问题深度优先遍历实例
2021/06/20 Python
【DOTA2】总决赛血虐~ XTREME GAMING vs MAGMA - OGA DOTA PIT 2022 CN
2022/04/02 DOTA
Android开发之底部导航栏的快速实现
2022/04/28 Java/Android
Java 死锁解决方案
2022/05/11 Java/Android