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中的五种异常处理机制介绍
Sep 02 Python
使用grappelli为django admin后台添加模板
Nov 18 Python
简介Django框架中可使用的各类缓存
Jul 23 Python
Python3 queue队列模块详细介绍
Jan 05 Python
Python批处理更改文件名os.rename的方法
Oct 26 Python
python 字典操作提取key,value的方法
Jun 26 Python
用python的turtle模块实现给女票画个小心心
Nov 23 Python
python numpy 矩阵堆叠实例
Jan 17 Python
关于Python 中的时间处理包datetime和arrow的方法详解
Mar 19 Python
Python绘制动态水球图过程详解
Jun 03 Python
Python logging模块handlers用法详解
Aug 14 Python
Python3 使用pip安装git并获取Yahoo金融数据的操作
Apr 08 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
这部番真是良心,画质好到像风景区,剧情让人跟着小公会热血沸腾
2020/03/10 日漫
一个简单的域名注册情况查询程序
2006/10/09 PHP
详谈PHP文件目录基础操作
2014/11/11 PHP
PHP贪婪算法解决0-1背包问题实例分析
2015/03/23 PHP
PHP购物车类Cart.class.php定义与用法示例
2016/07/20 PHP
判断客户端浏览器是否安装了Flash插件的多种方法
2010/08/11 Javascript
jquery简单瀑布流实现原理及ie8下测试代码
2013/01/23 Javascript
浏览器页面区域大小的js获取方法
2013/09/21 Javascript
JQuery中DOM加载与事件执行实例分析
2015/06/13 Javascript
基于ajax实现文件上传并显示进度条
2015/08/03 Javascript
使用Script元素发送JSONP请求的方法
2016/06/12 Javascript
有关suggest快速删除后仍然出现下拉列表的bug问题
2016/12/02 Javascript
javascript实现右下角广告框效果
2017/02/01 Javascript
关于 angularJS的一些用法
2017/11/29 Javascript
js实现以最简单的方式将数组元素添加到对象中的方法
2017/12/20 Javascript
微信小程序城市选择及搜索功能的方法
2019/03/22 Javascript
快速搭建Node.js(Express)用户注册、登录以及授权的方法
2019/05/09 Javascript
通过Nodejs搭建网站简单实现注册登录流程
2019/06/14 NodeJs
js判断复选框是否选中的方法示例【基于jQuery】
2019/10/10 jQuery
如何通过JS实现日历简单算法
2020/10/14 Javascript
Js实现粘贴上传图片的原理及示例
2020/12/09 Javascript
JavaScript实现切换多张图片
2021/01/27 Javascript
[04:50]2019DOTA2高校联赛秋季赛四强集锦
2019/12/27 DOTA
Python实现全角半角转换的方法
2014/08/18 Python
Python random模块用法解析及简单示例
2017/12/18 Python
Pycharm 创建 Django admin 用户名和密码的实例
2018/05/30 Python
Python实现的从右到左字符串替换方法示例
2018/07/06 Python
Python模拟自动存取款机的查询、存取款、修改密码等操作
2018/09/02 Python
基于Python爬取51cto博客页面信息过程解析
2020/08/25 Python
python模拟点击在ios中实现的实例讲解
2020/11/26 Python
CSS3实现时间轴效果
2016/07/11 HTML / CSS
教师个人自我评价范文
2014/04/13 职场文书
干部个人对照检查材料
2014/08/25 职场文书
2015年母亲节寄语
2015/03/23 职场文书
2015年行政部工作总结
2015/04/28 职场文书
python字典的元素访问实例详解
2021/07/21 Python