Python并发请求下限制QPS(每秒查询率)的实现代码

 更新时间:2020年06月05日 10:38:42   作者:Jiuh-star  
这篇文章主要介绍了Python并发请求下限制QPS(每秒查询率)实现方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  前两天有一个需求,需要访问某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(每秒查询率)实现内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • matplotlib 纵坐标轴显示数据值的实例

    matplotlib 纵坐标轴显示数据值的实例

    今天小编就为大家分享一篇matplotlib 纵坐标轴显示数据值的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • Python全栈之学习CSS(1)

    Python全栈之学习CSS(1)

    这篇文章主要为大家介绍了Python全栈之CSS,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • Python实现快速生成SQL语句的示例详解

    Python实现快速生成SQL语句的示例详解

    这篇文章主要介绍了如何使用Python中的字符串操作和数据结构,以及一些库来自动生成SQL语句的技巧,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-04-04
  • Python实现使用dir获取类的方法列表

    Python实现使用dir获取类的方法列表

    今天小编就为大家分享一篇Python实现使用dir获取类的方法列表,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • Python使用线程来接收串口数据的示例

    Python使用线程来接收串口数据的示例

    今天小编就为大家分享一篇Python使用线程来接收串口数据的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07
  • Python数据分析Pandas Dataframe排序操作

    Python数据分析Pandas Dataframe排序操作

    这篇文章主要介绍了Python数据分析Pandas Dataframe排序操作,数据的排序是比较常用的操作,DataFrame 的排序分为两种,一种是对索引进行排序,另一种是对值进行排序,接下来就分别都介绍一下,需要的小伙伴可以参考一下
    2022-05-05
  • python中文分词教程之前向最大正向匹配算法详解

    python中文分词教程之前向最大正向匹配算法详解

    中文分词是中文文本处理的一个基础性工作,然而长久以来,在Python编程领域,一直缺少高准确率、高效率的分词组件。下面这篇文章主要给大家介绍了关于python中文分词教程之前向最大正向匹配算法的相关资料,需要的朋友可以参考下。
    2017-11-11
  • 对python 判断数字是否小于0的方法详解

    对python 判断数字是否小于0的方法详解

    今天小编就为大家分享一篇对python 判断数字是否小于0的方法详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • Python一句代码实现找出所有水仙花数的方法

    Python一句代码实现找出所有水仙花数的方法

    今天小编就为大家分享一篇Python一句代码实现找出所有水仙花数的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-11-11
  • python的图形用户界面介绍

    python的图形用户界面介绍

    大家好,本篇文章主要讲的是python的图形用户界面介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01

最新评论