我使用Flask框架公开了一个Web服务。
此服务用作外部API,对每秒应调用的次数有限制。
在正常情况下,对我的API的多次调用会导致生成多个线程,并且在不对每秒请求数进行任何控制的情况下调用外部API。
是否有一种方法可以将请求排入Web服务,然后以限制方式调用外部API。
欢迎任何其他想法。
编辑:
答案 0 :(得分:1)
一种方法是包装请求,以便速率限制失败将导致指数退避,直到找到可接受的速率。
在下面的示例中,它将继续重试请求,直到成功,每次失败时请求之间的等待时间越来越长,最多允许的重试次数(n_max
)。等待重试请求的秒数呈指数级增长(1,2,4,8,16,32等)。
以下是使用requests
的示例。捕获错误和识别速率限制错误的细节取决于您用于发出请求的库以及外部api返回的错误类型,但退避算法应该是相同的。
def call_backoff(request_func, n_max=10):
n = 0
while n < n_max:
error = False
try:
response = request_func()
except errors.HttpError as e:
# You can test here if this is a rate error
# and not some other error. You can decide how to handle
# other errors.
error = True
if not_a_rate_error:
raise
if response.status_code == 429:
error = True
if not error:
return response
milli = random.randint(1, 1000)
secs = (2 ** n) + milli / 1000.0
time.sleep(secs)
n += 1
# You can raise an error here if you'd like
return None