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

FastAPI中用asyncio.run()启动后台任务后无法访问API及Swagger的咨询

问题原因

你调用asyncio.run(startup())后,代码会卡在这一行永远执行下去——因为startup函数里的asyncio.gather(*tasks)会等待所有监控任务完成,而每个monitor函数都是无限循环,永远不会结束。这就导致后面的uvicorn.run()根本没机会执行,API服务自然无法启动。

解决方案

改用FastAPI的启动事件钩子来启动后台任务,同时把同步的HTTP请求换成异步实现,避免阻塞事件循环:

  1. 使用@app.on_event("startup")装饰器标记启动时要执行的函数,FastAPI会在服务启动后自动运行它,且不会阻塞主线程。
  2. 替换requests库为异步HTTP客户端aiohttp,因为同步请求会卡住整个异步事件循环。
修正后的完整代码

首先安装依赖:

pip install aiohttp

代码:

import asyncio
import aiohttp
from fastapi import FastAPI

app = FastAPI()

monitor_data = [
    {"url": "https://endpoint_1/", "type": "https", "Interval": 30},
    {"url": "https://endpoint_2/", "type": "https", "Interval": 60}
]

@app.get('/')
async def amialive():
    return "Live"

async def monitor(url, interval):
    async with aiohttp.ClientSession() as session:
        while True:
            try:
                async with session.get(url) as response:
                    print(f"{url}: {response.status_code}")
            except Exception as e:
                print(f"{url} 请求失败: {str(e)}")
            await asyncio.sleep(interval)

@app.on_event("startup")
async def startup():
    for data in monitor_data:
        url = data["url"]
        interval = data["Interval"]
        # 创建后台任务,无需等待完成
        asyncio.create_task(monitor(url, interval))

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("network_monitoring:app", host="0.0.0.0", port=8000, reload=True)
说明
  • @app.on_event("startup")装饰的函数会在FastAPI服务启动后异步执行,不会阻塞API端点的运行。
  • 使用asyncio.create_task创建监控任务后直接返回,不需要await asyncio.gather,这样启动函数会立即完成,不会卡住。
  • aiohttp的异步请求保证了监控任务不会阻塞事件循环,API和后台任务可以同时正常工作。

内容的提问来源于stack exchange,提问作者Praveen K M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:45:49