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数组的处理代码
Jan 04 Python
CentOS 6.X系统下升级Python2.6到Python2.7 的方法
Oct 12 Python
Python中垃圾回收和del语句详解
Nov 15 Python
Python3多线程版TCP端口扫描器
Aug 31 Python
pytorch常见的Tensor类型详解
Jan 15 Python
Python连接Oracle之环境配置、实例代码及报错解决方法详解
Feb 11 Python
python+opencv3生成一个自定义纯色图教程
Feb 19 Python
python不到50行代码完成了多张excel合并的实现示例
May 28 Python
Python爬虫如何应对Cloudflare邮箱加密
Jun 24 Python
python mongo 向数据中的数组类型新增数据操作
Dec 05 Python
Python生成九宫格图片的示例代码
Apr 14 Python
教你如何使用Python Tkinter库制作记事本
Jun 10 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
phpmail类发送邮件函数代码
2012/02/20 PHP
php使用curl简单抓取远程url的方法
2015/03/13 PHP
PHP MVC框架skymvc支持多文件上传
2016/05/26 PHP
Yii框架Session与Cookie使用方法示例
2019/10/14 PHP
Ext.FormPanel 提交和 Ext.Ajax.request 异步提交函数的区别
2009/11/12 Javascript
jQuery1.5.1 animate方法源码阅读
2011/04/05 Javascript
AngularJS + Node.js + MongoDB开发的基于高德地图位置的通讯录
2015/01/02 Javascript
jQuery绑定事件的几种实现方式
2016/05/09 Javascript
JS选取DOM元素的简单方法
2016/07/08 Javascript
浅谈javascript:两种注释,声明变量,定义函数
2016/09/29 Javascript
基于Jquery Ajax type的4种类型(详解)
2017/08/02 jQuery
JSON stringify方法原理及实例解析
2020/10/23 Javascript
在nuxt中使用路由重定向的实例
2020/11/06 Javascript
[20:57]Ti4主赛事第三天开幕式
2014/07/21 DOTA
Python with的用法
2014/08/22 Python
python读取word文档的方法
2015/05/09 Python
浅谈flask截获所有访问及before/after_request修饰器
2018/01/18 Python
Python之使用adb shell命令启动应用的方法详解
2019/01/07 Python
Python切片操作去除字符串首尾的空格
2019/04/22 Python
浅析Windows 嵌入python解释器的过程
2019/07/26 Python
Python栈的实现方法示例【列表、单链表】
2020/02/22 Python
Pycharm自动添加文件头注释和函数注释参数的方法
2020/10/23 Python
详解基于python的图像Gabor变换及特征提取
2020/10/26 Python
Laravel的加密解密与哈希实例讲解
2021/03/24 PHP
人力资源管理专业毕业生推荐信
2013/11/07 职场文书
初二政治教学反思
2014/01/12 职场文书
旷课检讨书3000字
2014/02/04 职场文书
校园安全教育广播稿
2014/02/17 职场文书
《植物妈妈有办法》教学反思
2014/02/25 职场文书
保险公司晨会主持词
2014/03/22 职场文书
厨师个人自我鉴定范文
2014/04/19 职场文书
党的群众路线教育实践活动通讯稿
2014/09/10 职场文书
区政府领导班子个人对照检查材料
2014/09/25 职场文书
教师党员批评与自我批评发言稿
2014/10/15 职场文书
担保贷款承诺书
2015/04/30 职场文书
辞职信怎么写?你都知道吗?
2019/06/24 职场文书