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登录Gmail并发送Gmail邮件的教程
Apr 17 Python
Python中用psycopg2模块操作PostgreSQL方法
Nov 28 Python
在Pandas中处理NaN值的方法
Jun 25 Python
python opencv 读取图片 返回图片某像素点的b,g,r值的实现方法
Jul 03 Python
Python图像处理PIL各模块详细介绍(推荐)
Jul 17 Python
Flask框架单例模式实现方法详解
Jul 31 Python
nginx黑名单和django限速,最简单的防恶意请求方法分享
Aug 09 Python
使用pandas 将DataFrame转化成dict
Dec 10 Python
基于MSELoss()与CrossEntropyLoss()的区别详解
Jan 02 Python
Python插入Elasticsearch操作方法解析
Jan 19 Python
python 读txt文件,按‘,’分割每行数据操作
Jul 05 Python
Python内置包对JSON文件数据进行编码和解码
Apr 12 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
英雄试炼之肉山谷—引领RPG新潮流
2020/04/20 DOTA
天津市收音机工业发展史
2021/03/04 无线电
mayfish 数据入库验证代码
2010/04/30 PHP
PHP内核探索:变量概述
2014/01/30 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(八)
2014/06/23 PHP
让ThinkPHP支持大小写url地址访问的方法
2014/10/31 PHP
JavaScript中Math对象使用说明
2008/01/16 Javascript
用JavaScript显示随机图像或引用
2009/04/21 Javascript
document.getElementById的简写方式(获取id对象的简略写法)
2010/09/10 Javascript
JavaScript与Image加载事件(onload)、加载状态(complete)
2011/02/14 Javascript
关于event.cancelBubble和event.stopPropagation()的区别介绍
2011/12/11 Javascript
Javascript 页面模板化很多人没有使用过的方法
2012/06/05 Javascript
使用javascript实现ListBox左右全选,单选,多选,全请
2013/11/07 Javascript
js的正则test,match,exec详细解析
2014/01/29 Javascript
使用jquery实现以post打开新窗口
2014/03/19 Javascript
JS实现在网页中弹出一个输入框的方法
2015/03/03 Javascript
前端js文件合并的三种方式推荐
2016/05/19 Javascript
了解VUE的render函数的使用
2017/06/08 Javascript
JavaScript数据类型和变量_动力节点Java学院整理
2017/06/26 Javascript
JQuery基于FormData异步提交数据文件
2020/09/01 jQuery
Ant Design Pro 之 ProTable使用操作
2020/10/31 Javascript
Python中的测试模块unittest和doctest的使用教程
2015/04/14 Python
使用Python的Scrapy框架十分钟爬取美女图
2016/12/26 Python
python内存动态分配过程详解
2019/07/15 Python
基于打开pycharm有带图片md文件卡死问题的解决
2020/04/24 Python
Django 实现 Websocket 广播、点对点发送消息的代码
2020/06/03 Python
python中用ggplot绘制画图实例讲解
2021/01/26 Python
美国护肤咨询及美容产品电商:Askderm
2017/02/24 全球购物
Merrell迈乐澳大利亚网站:购买户外登山鞋
2017/05/28 全球购物
英国第一的滑雪服装和装备零售商:Snow+Rock
2020/02/01 全球购物
广州一家公司的.NET面试题
2016/06/11 面试题
工作失误检讨书范文大全
2014/01/13 职场文书
爱情保证书范文
2014/02/01 职场文书
酒店总经理职务说明书
2014/02/26 职场文书
基层党员对照检查材料
2014/08/25 职场文书
医院领导班子整改方案
2014/10/01 职场文书