Files
lawyers/utils/rate_limiter.py
T
2026-03-02 00:19:48 +08:00

77 lines
2.0 KiB
Python

"""
全局请求速率限制器
确保代理每秒不超过5次请求
"""
import time
import threading
from collections import deque
class RateLimiter:
"""
令牌桶算法实现的速率限制器
"""
def __init__(self, max_requests_per_second: int = 5):
"""
初始化速率限制器
Args:
max_requests_per_second: 每秒最大请求数
"""
self.max_requests = max_requests_per_second
self.requests = deque()
self.lock = threading.RLock()
def acquire(self):
"""
获取请求权限,如果需要则等待
"""
with self.lock:
now = time.time()
# 清理超过1秒的请求记录
while self.requests and now - self.requests[0] >= 1.0:
self.requests.popleft()
# 如果当前请求数已达上限,等待
if len(self.requests) >= self.max_requests:
# 计算需要等待的时间
wait_time = 1.0 - (now - self.requests[0])
if wait_time > 0:
time.sleep(wait_time)
return self.acquire() # 递归调用以重新检查
# 记录这次请求
self.requests.append(now)
def can_make_request(self) -> bool:
"""
检查是否可以立即发起请求(非阻塞)
"""
with self.lock:
now = time.time()
# 清理超过1秒的请求记录
while self.requests and now - self.requests[0] >= 1.0:
self.requests.popleft()
return len(self.requests) < self.max_requests
# 全局速率限制器实例
global_rate_limiter = RateLimiter(max_requests_per_second=5)
def wait_for_request():
"""
等待直到可以发起请求
"""
global_rate_limiter.acquire()
def can_request_now() -> bool:
"""
检查是否可以立即发起请求
"""
return global_rate_limiter.can_make_request()