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实现比较两个列表(list)范围
Jun 12 Python
Python使用面向对象方式创建线程实现12306售票系统
Dec 24 Python
Python3 XML 获取雅虎天气的实现方法
Feb 01 Python
python自动化报告的输出用例详解
May 30 Python
python多行字符串拼接使用小括号的方法
Mar 19 Python
基于python的ini配置文件操作工具类
Apr 24 Python
python Qt5实现窗体跟踪鼠标移动
Dec 13 Python
Python tkinter常用操作代码实例
Jan 03 Python
Django 删除upload_to文件的步骤
Mar 30 Python
python中sys模块是做什么用的
Aug 16 Python
Django项目如何获得SSL证书与配置HTTPS
Apr 30 Python
Python3.10的一些新特性原理分析
Sep 15 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
在Windows中安装Apache2和PHP4的权威指南
2006/10/09 PHP
swoole_process实现进程池的方法示例
2018/10/29 PHP
thinkphp框架类库扩展操作示例
2019/11/26 PHP
javascript编程起步(第四课)
2007/02/27 Javascript
JavaScript asp.net 获取当前超链接中的文本
2009/04/14 Javascript
jquery imgareaselect 使用利用js与程序结合实现图片剪切
2009/07/30 Javascript
jQuery 点击图片跳转上一张或下一张功能的实现代码
2010/03/12 Javascript
js 小数取整的函数
2010/05/10 Javascript
基于jquery的checkbox下拉框插件代码
2010/06/25 Javascript
JS获取图片实际宽高及根据图片大小进行自适应
2013/08/11 Javascript
javascript判断两个IP地址是否在同一个网段的实现思路
2013/12/13 Javascript
js字符串转换成数字与数字转换成字符串的实现方法
2014/01/08 Javascript
在NodeJS中启用ECMAScript 6小结(windos以及Linux)
2014/07/15 NodeJs
javascript中的altKey 和 Event属性大全
2015/11/06 Javascript
快速学习jQuery插件 Cookie插件使用方法
2015/12/01 Javascript
js调用webservice构造SOAP进行身份验证
2016/04/27 Javascript
jQuery EasyUI学习教程之datagrid点击列表头排序
2016/07/09 Javascript
JS实现图片延迟加载并淡入淡出效果的简单方法
2016/08/25 Javascript
js遍历map javaScript遍历map的简单实现
2016/08/26 Javascript
Angular 应用技巧总结
2016/09/14 Javascript
概述一个页面从输入URL到页面加载完的过程
2016/12/16 Javascript
jQuery插件JWPlayer视频播放器用法实例分析
2017/01/11 Javascript
jQuery插件FusionCharts实现的Marimekko图效果示例【附demo源码】
2017/03/24 jQuery
jQuery Ajax 实现分页 kkpager插件实例代码
2017/08/10 jQuery
javascript计算对象长度的方法
2017/10/25 Javascript
Angular @HostBinding()和@HostListener()用法
2018/03/05 Javascript
Webstorm2016使用技巧(SVN插件使用)
2018/10/29 Javascript
vue.js实现的全选与全不选功能示例【基于elementui】
2018/12/03 Javascript
微信小程序学习总结(五)常见问题实例小结
2020/06/04 Javascript
pandas进行时间数据的转换和计算时间差并提取年月日
2019/07/06 Python
Python 生成器,迭代,yield关键字,send()传参给yield语句操作示例
2019/10/12 Python
python报错TypeError: ‘NoneType‘ object is not subscriptable的解决方法
2020/11/05 Python
结婚典礼证婚词
2014/01/08 职场文书
王兆力在市委党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
小平小道观后感
2015/06/09 职场文书
详解MySql中InnoDB存储引擎中的各种锁
2022/02/12 MySQL