前两天有一个需求,需要访问某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测试程序的qps和响应时间代码_Python并发请求下限制QPS(每秒查询率)的实现代码...相关推荐

  1. python多进程并发代码_Python并发编程系列之多进程(multiprocessing)

    1引言 本篇博文主要对Python中并发编程中的多进程相关内容展开详细介绍,Python进程主要在multiprocessing模块中,本博文以multiprocessing种Process类为中心, ...

  2. python中下划线的5种含义_python中的下划线含义

    单下划线和双下划线在Python变量和方法名称中都有含义.其中一些含义仅仅是按照惯例,作为给程序员的提示,而另外一些则由Python解释器执行. 在本文中,主要讨论以下五种下划线模式和命名约定,以及它 ...

  3. 缩短服务器响应时间,美国服务器高并发情况下缩短响应时间的方法

    美国服务器网站的响应时间是指系统响应请求的时间.网站响应时间越短,用户访问美国服务器网站的速度就越快.虽然响应时间并不直接反映网站的性能,但它在一定程度上反映了美国服务器网站系统的处理能力.下面将讨论 ...

  4. python如何删除代码_Python如何删除除字母和数字之外的所有字符?(代码示例)

    字符串操作是日常编码和Web开发中非常重要的任务:例如:HTTP查询中的大多数请求和响应都是字符串形式,有时我们需要删除一些无用的数据.下面本篇文章就来给大家介绍一些Python方法来将指定字符串中除 ...

  5. 为什么用python缩进来划分代码_Python 为什么抛弃累赘的花括号,使用缩进来划分代码块?...

    大家好,这是"Python为什么"系列节目的文字稿(文末有观看地址). 本期话题:Python 为什么使用缩进来划分代码块,而不像其它语言使用花括号 {} 或者 "end ...

  6. python怎么清除代码_Python如何清空列表?清空列表的4种方法(代码示例)

    通过Python语言提供的不同构造的方法可以有许多方法来清空列表,下面本篇文章就来给带大家介绍Python中4种清空列表的方法,希望对大家有所帮助. 方法1:重新初始化列表 可以重初始化列表,初始化该 ...

  7. python 如何修改字典的key值_Python编程:如何把元组/字典作为参数传递给函数(附代码)...

    学习编程语言的读者对于函数参数的传递应该都不陌生,目前业内已经有多种高级语言允许定义个数可变的参数,这样的好处是可以在调用函数时传入任意多个参数. python可变参数 当然,Python 也不例外, ...

  8. python爬虫如何爬亚马逊_Python爬取当当、京东、亚马逊图书信息代码实例

    注:1.本程序采用MSSQLserver数据库存储,请运行程序前手动修改程序开头处的数据库链接信息 2.需要bs4.requests.pymssql库支持 3.支持多线程 from bs4 impor ...

  9. python多线程执行其他模块的文件_python并发编程--进程线程--其他模块-从菜鸟到老鸟(三)...

    concurrent模块 1.concurrent模块的介绍 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor:线程池,提供异步调用 Proc ...

最新文章

  1. OpenCV使用 GrabCut 算法进行交互式前景提取
  2. 零基础学习Python需要注意的几个点,Python培训机构排名
  3. 支持html5浏览器速查
  4. python学习使用
  5. 寒假每日一题(入门组)【week1 完结】
  6. 电脑分辨率设置工具_干货分享:PPT 导出高清分辨率图片的四种方法
  7. Spring思维导图(IOC篇)
  8. strchr与strstr函数
  9. Java容器有哪些?
  10. Python符号计算入门及隐函数图像绘制
  11. 用户界面和兼容性测试
  12. HDU 2665 Kth number(主席树静态区间第K大)题解
  13. 系统子系统_GPRS子系统流程图
  14. 关于一个类中方法的调用
  15. atitit.按钮光标滑过高亮切换以及其他动态效果的实现css html js --attilax总结
  16. Spring的9种设计模式(二)
  17. 台式机黑苹果Mac OS Big Sur 11.3.1安装指引
  18. python因子分析 ic值 函数_spss问卷调查因子分析定义变量及内容输入
  19. Axure原型设计工具--产品经理必备
  20. ceph存储 Ceph管理平台Calamari的架构与功能分析

热门文章

  1. js数组的排序 sort详解
  2. 入门指南目录页 -PaddlePaddle 飞桨 入门指南 FAQ合集-深度学习问题
  3. HiCar基本功能介绍
  4. 深度学习到底有哪些卷积?
  5. 客快物流大数据项目(十三):Docker镜像
  6. linux下用js生成xml,js2xml:将javascript字符串转换为xml
  7. Android 侧滑栏 (DrawerLayout)
  8. Android WebView 加载http网址的h5 不显示
  9. gvim plugin管理
  10. [BZOJ3337] ORZJRY I --块状链表大毒瘤