You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用aiohttp每0.1秒发送API请求并满足条件时提前退出的实现问题

问题根因

你当前的代码是串行执行每个请求的完整流程:for循环中每一轮都要依次等待asyncio.sleep(0.1)、请求发送、响应返回、结果校验全部完成,才会进入下一轮。await会阻塞当前协程的执行,所以最终的请求间隔等于「0.1s + 单次请求往返耗时」,自然达不到预期的10次/秒速率。
另外你当前的代码已经在共享ClientSession了,还可以通过优化连接池配置进一步提升性能。

优化方案

核心思路是分离请求调度和响应处理:用一个独立协程严格按0.1s间隔发送请求,每个请求的响应处理放到后台异步运行,一旦有请求满足终止条件,就触发全局停止信号,终止所有未完成的任务。

修改后的代码如下:

import time
import datetime
import aiohttp
import asyncio

url = 'http://www.randomnumberapi.com/api/v1.0/random'
# 终止信号
stop_event = asyncio.Event()
# 存储所有未完成的请求任务
pending_tasks = set()

async def handle_response(response_future, req_id):
    """异步处理请求响应"""
    try:
        response = await response_future
        answer_list = await response.json()
        ans = answer_list[0]
        print(f"请求{req_id}返回结果:{ans}")
        # 替换成你自己的校验逻辑
        if req_id == 25:
            print('early exit condition met')
            stop_event.set()
    except Exception as e:
        print(f"请求{req_id}出错:{str(e)}")

async def main():
    # 优化session配置,开启连接池复用,适配同端点高频请求
    connector = aiohttp.TCPConnector(
        limit=100,  # 连接池大小,根据并发量调整
        ttl_dns_cache=300,
        enable_cleanup_closed=True
    )
    async with aiohttp.ClientSession(connector=connector) as session:
        req_id = 0
        # 最多发100次请求,或者收到停止信号就终止
        while req_id < 100 and not stop_event.is_set():
            start_schedule = time.time()
            print(f'{req_id}: 发送时间 {datetime.datetime.now()}')
            # 发起请求不等待响应,直接丢给后台处理
            resp_future = session.get(url)
            task = asyncio.create_task(handle_response(resp_future, req_id))
            pending_tasks.add(task)
            task.add_done_callback(pending_tasks.discard)

            req_id += 1
            # 精准控间隔,补偿调度耗时,避免累积误差
            cost = time.time() - start_schedule
            sleep_time = max(0, 0.1 - cost)
            await asyncio.sleep(sleep_time)
        
        # 等待所有未完成的任务结束,不需要保留结果的话也可以直接取消
        await asyncio.gather(*pending_tasks, return_exceptions=True)
        return req_id - 1

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    ans = loop.run_until_complete(main())
    print(ans)

优化说明

  • 发送请求的协程仅负责按间隔发起请求,不会等待响应返回,所以请求发送间隔严格控制在0.1s,符合10次/秒的速率限制要求
  • 所有请求的IO等待是并行处理的,充分发挥异步的性能优势
  • 复用ClientSession的同时优化了TCP连接池配置,同一个端点的请求会复用TCP连接,减少三次握手等额外开销,进一步降低请求耗时
  • 用事件对象实现提前终止逻辑,一旦有请求满足条件就能立即停止发送新请求

内容的提问来源于stack exchange,提问作者user5364303

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 22:36:04