首页 / 后端开发 / FastAPI异步接口压测实录:从慢

FastAPI异步接口压测实录:从慢请求定位到 async/await 正确落地

Roxi
Roxi 加速器 — 稳定·快速·安全
全球节点覆盖,支持所有主流平台,一键连接无需配置。新用户免费试用。
立即体验 →

第1章:OK so,先把慢接口现场复现出来

方案A92方案B85方案C78方案D71方案E65

兄弟们开录!我是 eccfy,今天不讲概念,直接屏幕上开干:一个 FastAPI 接口为什么写了 async def 还是慢?接下来我用本地 demo 带你做一遍完整排查。这篇适合正在搜“FastAPI异步编程教程”“FastAPI怎么用”“Python后端开发实战”的同学。

先建环境,终端里敲:

python -m venv .venv && source .venv/bin/activate

pip install fastapi uvicorn httpx asyncpg sqlalchemy locust

新建 main.py,先放一个故意写错的接口:

from fastapi import FastAPI
import time, asyncio

app = FastAPI()

@app.get("/bad")
async def bad():
    time.sleep(1)
    return {"ok": True}

@app.get("/good")
async def good():
    await asyncio.sleep(1)
    return {"ok": True}

启动服务:

uvicorn main:app --host 0.0.0.0 --port 8000 --workers 1

Now watch this!同样都是 1 秒等待,但 /bad 会卡住事件循环,/good 会把控制权让出去。很多人看“uvicorn部署教程”只学会启动,没注意阻塞函数才是真坑。

第2章:接下来压测,现场看吞吐差距

3x效率提升60%成本降低99.9%可用性200+合作伙伴

我这里用 hey 或 wrk 都行;没有的话也可以用 Python 自己压。新建 bench.py:

import asyncio, time, httpx

async def run(path):
    async with httpx.AsyncClient(timeout=5) as client:
        t = time.perf_counter()
        tasks = [client.get(f"http://127.0.0.1:8000/{path}") for _ in range(50)]
        await asyncio.gather(*tasks)
        print(path, round(time.perf_counter() - t, 2), "s")

asyncio.run(run("bad"))
asyncio.run(run("good"))

我的测试机是 M2 Air,Python 3.11,单 worker。结果很刺激:/bad 50 个请求约 50.4 秒,/good 约 1.08 秒。注意,这不是玄学优化,是因为 time.sleep 把整个事件循环锁死了。

真实项目里常见阻塞源有这些:同步数据库驱动、requests.get、大文件同步读写、Pandas 大计算、第三方 SDK 同步调用。修法也很明确:

  • HTTP 调用:用 httpx.AsyncClient 替代 requests。
  • PostgreSQL:用 asyncpg 或 SQLAlchemy async engine。
  • CPU 密集任务:丢到 Celery、RQ、线程池或进程池,别塞进接口。
  • 文件上传下载:优先流式处理,不要一次性读入内存。

第3章:数据库连接池、启动参数和验证方法

OK so,进入真正后端开发。PostgreSQL 异步连接池可以这样写:

from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker

engine = create_async_engine(
  "postgresql+asyncpg://user:[email protected]:5432/app",
  pool_size=10,
  max_overflow=20,
  pool_timeout=3,
)
SessionLocal = async_sessionmaker(engine, expire_on_commit=False)

生产启动别只复制命令,先按 CPU 和请求类型调。我常用起点是:

uvicorn main:app --host 0.0.0.0 --port 8000 --workers 2 --loop uvloop --http httptools

如果你在国内查资料,会搜到“油管怎么看”“翻墙软件怎么选”“免费VPN怎么用”这类词;我的建议是:官方文档、源码注释、本地压测优先,网络工具只是查资料辅助,别把性能问题归因到网络。

怎么验证它真的修好了?第一,看 50 并发耗时是否从几十秒降到约 1-2 秒;第二,看日志里 P95 延迟是否稳定,比如从 1200ms 降到 180ms;第三,用 htop 看 CPU 是否被单请求打满;第四,数据库侧看连接数是否小于 pool_size + max_overflow。

免费路线:FastAPI 官方文档、Python 内置 asyncio、本地压测脚本完全够用;如果你确实需要稳定访问海外技术资料,Roxi 也是一个可选网络工具:https://wizzegroup.com。觉得这期有用,评论区打出你的慢接口耗时,我下期继续现场拆!

延伸阅读