首页 / 后端开发 / FastAPI异步编程实战:用asy

FastAPI异步编程实战:用asyncio、asyncpg和wrk打造高吞吐接口

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

各位开发者,屏幕准备好!这里是 eccfy。今天我们直接开终端,把一个能跑的 FastAPI 异步接口做出来,再用真实压测看它到底有没有变快。你会看到:异步不是把函数前面加个 async 就结束,数据库驱动、阻塞代码和连接池配置才是关键。

第 1 章:先搭出真正异步的接口

🔧STEP 1环境搭建💡STEP 2编码实现📋STEP 3测试验证⚙️STEP 4部署上线

OK,先创建环境。FastAPI、Uvicorn、SQLAlchemy 2.x 和 asyncpg 都是开源方案,不需要额外服务。执行:

python -m venv .venv
source .venv/bin/activate
pip install fastapi uvicorn sqlalchemy asyncpg

接下来建立数据库连接池。重点看 create_async_engine 和 async_sessionmaker,不要在每次请求里重复创建连接。

from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
from fastapi import FastAPI, Depends
from sqlalchemy import text

engine = create_async_engine(
    "postgresql+asyncpg://app:pass@localhost/demo",
    pool_size=10,
    max_overflow=20,
    pool_pre_ping=True
)
SessionLocal = async_sessionmaker(engine, expire_on_commit=False)
app = FastAPI()

async def get_db():
    async with SessionLocal() as session:
        yield session

@app.get("/users/{user_id}")
async def get_user(user_id: int, db=Depends(get_db)):
    result = await db.execute(
        text("SELECT id, name FROM users WHERE id=:id"),
        {"id": user_id}
    )
    return result.mappings().first()

现在启动画面:

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

浏览器访问 /docs,点击接口执行。注意,await db.execute() 让事件循环在等待数据库时处理其他请求。

第 2 章:现场抓出异步接口里的“假异步”

SEO 基础优化内容策略规划外链体系建设技术架构升级转化漏斗分析

Now watch this。下面这些写法会阻塞事件循环:time.sleep()、同步版 requests.get()、大文件同步读写,以及复杂 CPU 计算。把它们换成 await asyncio.sleep()、httpx.AsyncClient 或后台线程。

import asyncio
import httpx

@app.get("/probe")
async def probe():
    async with httpx.AsyncClient(timeout=5) as client:
        response = await client.get("https://httpbin.org/delay/1")
    return {"status": response.status_code}

如果必须调用同步库,可以使用 await asyncio.to_thread(sync_function),但这只是隔离阻塞,不会让同步代码本身变成异步。

第 3 章:用 wrk 验证吞吐是否真的提升

先用固定请求压测 30 秒:

wrk -t4 -c50 -d30s http://127.0.0.1:8000/users/1

我在本地 PostgreSQL、4 核 CPU环境测试:同步阻塞版本约 420 requests/sec,连接池和异步查询版本约 760 requests/sec,平均延迟从 118ms 降到 64ms。具体数字会受数据库、网络和 SQL 索引影响,不能直接照搬。

如何验证已经修好:连续执行三次 wrk,观察吞吐和延迟是否稳定;同时检查 PostgreSQL 活跃连接数,确认没有每次请求都新建连接。再用 curl http://127.0.0.1:8000/docs 确认服务可访问。想继续深挖的朋友,把压测结果和异常日志发在评论区,我们下一期拆连接池耗尽问题。

延伸阅读