asyncio.run()不可在运行中的事件循环内调用,应改用asyncio.get_event_loop().run_until_complete();http客户端推荐httpx(易用)或aiohttp(可控);db驱动须用异步版本,否则需线程池规避阻塞;gather适合全成功场景,create_task适合流式/降级需求。

asyncio.run() 不能在已运行的事件循环里调用
微服务里常把异步逻辑塞进同步框架(比如 Flask、FastAPI 的依赖注入或中间件),一不小心就触发 RuntimeError: asyncio.run() cannot be called from a running event loop。这不是代码写错了,而是 asyncio 设计使然:asyncio.run() 只能启动顶层事件循环,不能嵌套。
实操建议:
- 在 FastAPI 中直接写
async def路由或依赖,让框架接管事件循环,别自己调asyncio.run() - 若必须从同步上下文启动异步调用(如 Celery 任务、旧版 Django 视图),改用
asyncio.get_event_loop().run_until_complete(...),但要确保当前线程已有 loop(否则需先asyncio.set_event_loop(asyncio.new_event_loop())) - 避免在 logging、__del__、atexit 回调中触发异步调用——这些地方没有可靠事件循环上下文
HTTP 客户端选 aiohttp 还是 httpx?
微服务间高频调用 HTTP 接口时,aiohttp 和 httpx 是最常用两个异步客户端,区别不在“能不能用”,而在连接复用、超时控制和类型提示是否开箱即用。
实操建议:
-
httpx.AsyncClient默认支持 HTTP/2、自动重试、更贴近 requests 的 API,适合快速迁移或需要强类型(配合 Pydantic)的场景 -
aiohttp.ClientSession对连接池控制更细(如connector=TCPConnector(limit=100)),适合高并发长连接、需精细调优的网关层 - 别混用:一个服务里统一用一种客户端;混用会多开事件循环资源,且
aiohttp的 session 生命周期管理比httpx更敏感——漏掉await session.close()或用完不await client.aclose()会导致连接泄漏
async def 函数里调 sync DB 驱动会阻塞整个事件循环
用 psycopg2、sqlite3 或 pymysql 这类纯同步驱动,在 async def 里直接调用 cursor.execute(),表面看能跑,实际会让整个协程挂起,吞掉所有并发收益。
实操建议:
- PostgreSQL 优先用
asyncpg(性能最好)或psycopg的异步版本(psycopg.AsyncConnection),别碰psycopg2 - MySQL 用
aiomysql或asyncmy,后者更轻量、无 C 依赖 - 真没法换驱动?只能用
loop.run_in_executor()包一层,但这是权宜之计:每次调用都开线程,高并发下线程池会成瓶颈,且异常堆栈变深、调试困难
asyncio.gather() 和 asyncio.create_task() 的调度差异
批量调用下游服务时,asyncio.gather() 看起来简洁,但它会等所有任务完成才返回;而 asyncio.create_task() 更灵活,适合需要流式响应、提前失败或按需取消的场景。
实操建议:
- 下游服务间无依赖、可并行、且必须全部成功才继续——用
asyncio.gather(*tasks, return_exceptions=True),加return_exceptions=True避免一个失败全崩 - 需要某次调用超时就立刻放弃后续(如降级策略)、或想边收结果边处理(如日志聚合)——用
asyncio.create_task()手动管理 task,并配合asyncio.wait()或asyncio.as_completed() - 别在循环里反复写
await asyncio.create_task(...):这等于串行执行。正确写法是先建好所有 task,再统一 await 或用asyncio.wait()
异步不是加个 async/await 就完事;微服务里真正难的是连接池生命周期、错误传播路径、以及同步/异步边界处的资源清理。这些地方没显式报错,但压测时延迟毛刺、连接数飙升、内存缓慢增长,八成出在这儿。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











