Python并发请求限制QPS的三种实现方案

Ruby
Ruby
发布时间:2026-10-14| 5人浏览过
原创

本文介绍在Python中使用GRequests进行高并发API请求时,如何通过三种方式限制每秒查询率(QPS)。内容涵盖基础的time.sleep阻塞法、精确的令牌桶算法实现,以及封装好的GRequests-Throttle库。针对低并发和高并发场景提供了具体的代码示例与性能对比,帮助开发者避免服务器拒绝响应并优化资源利用率。

背景与问题描述

此前遇到一个需求,需访问某API服务器获取数据。该服务器对QPS(每秒查询率)限制为2。由于限制较低,最初采用阻塞式请求即可满足。后续服务升级,QPS上限提升至20,原有的阻塞方式已无法充分利用带宽。因此改用GRequests进行并发请求,但发现并发速度过快导致服务器频繁返回错误码,造成大量资源浪费。为此,本文记录几种有效的节流(Throttle)方案:

基础限流方案:time.sleep阻塞法

以下示例均基于相同的前提条件,包含必要的包导入及数据初始化:


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)。然而,该方法存在精度不足的问题:随着数据量增大,实际QPS的方差也会随之增大,导致限流效果不够稳定。


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 = 请求准备时延 + 请求发送时延 + 令牌桶阻塞时延。其中,令牌桶阻塞时延 ≈ 1 - (请求准备时延 + 请求发送时延)。尽管精度提升,但该方法会导致CPU占用率看似较高(主要源于while pass循环),尽管实际有效计算负载很低。


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

GRequests-Throttle

这是一个基于令牌桶算法封装的GRequests修改版,使用方式极为简便。首先需安装grequests-throttle库(注:清华镜像源更新可能较慢,建议使用阿里镜像源):


pip install grequests-throttle

import grequests_throttle as gt

ret = gt.map(requests, rate=rate)
print(ret)

方案总结与建议

总结

若并发请求量较小,可直接使用time.sleep(1),实现简单快捷;若并发量较大,令牌桶算法能更充分地利用每一秒的带宽;若希望减少代码编写量,推荐使用GRequests-Throttle库进行流量控制。

关于Python并发请求下限制QPS的实现介绍至此。如需了解更多相关技术细节,可查阅本站往期文章或继续浏览后续内容。感谢支持!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。