从 Flask 到 FastAPI:Python Web 框架的异步化演进与选型实战

为什么现在谈 Flask 和 FastAPI 的选型变得紧迫了

大概在 2020 年之前,很多团队内部用 Flask 写个管理后台、快速验证个产品原型,是再自然不过的选择。它的语法简单,文档清晰,社区庞大,遇到问题几乎都能找到现成的扩展。但最近两年,尤其是在 AI 推理、实时数据接口、微服务网关这些新场景里,FastAPI 的讨论度明显压过了 Flask。这背后不是简单的“新框架替代旧框架”,而是一次从同步阻塞到异步非阻塞的底层架构迁移。

从 Flask 到 FastAPI:Python Web 框架的异步化演进与选型实战

我见过不少项目,初期为了快速上线,用 Flask 搭了个简单的 HTTP 服务。当用户量起来,接口需要频繁调用数据库、外部 API 或进行模型推理时,整个服务的响应时间开始变得不稳定,即使增加 Gunicorn 的 worker 数量,效果也有限。这时候团队才会意识到,问题可能不在代码逻辑,而在于 Flask 基于 WSGI 的同步请求处理模型。

核心分歧:WSGI 与 ASGI,两种不同的网关协议

理解 Flask 和 FastAPI 的差异,首先要抛开“轻量”或“性能”这类标签,去看它们底层的协议支撑。

Flask 建立在 WSGI (Web Server Gateway Interface) 之上。这是一个 2003 年制定的 Python 标准,设计目标是让 Web 服务器(如 Nginx)和 Python Web 应用之间有个统一的调用方式。WSGI 是同步的,一个请求对应一个线程(或进程)来处理,在处理完成并返回响应之前,这个线程会被完全占用。如果这个请求内部需要等待数据库 I/O 或者调用一个慢速的外部服务,线程就只能“干等着”,这就是所谓的阻塞。

FastAPI 则构建于 ASGI (Asynchronous Server Gateway Interface) 之上。ASGI 可以看作是 WSGI 的异步和精神继承者。它原生支持异步操作,允许单个线程在等待一个请求的 I/O 时,去处理其他请求的任务。这对于现代 Web 应用中大量存在的 I/O 密集型操作(网络请求、文件读写、数据库查询)来说,是革命性的变化。

你可以这样类比:WSGI 像是一条单车道,每辆车(请求)必须跑完全程,下一辆车才能上路。ASGI 则像是一个智能交通系统,车辆在路口等红灯(I/O 等待)时,系统可以调度其他路口的车辆通行。

性能对比:数字背后的工程现实

很多文章会直接甩出一个 benchmark,说 FastAPI 的 QPS 是 Flask 的几倍。这种对比需要谨慎看待。在纯 CPU 计算、几乎无 I/O 的场景下,两者的差距可能并不明显,因为瓶颈在 CPU 而不是框架。真正的差距出现在 I/O 密集的场景。

假设一个场景:你的接口需要先后调用一次数据库查询和一次第三方 HTTP API。在 Flask 的同步模型中,一个 worker 线程的时序是这样的:处理请求 -> 等待数据库响应(线程阻塞)-> 处理数据库结果 -> 等待 HTTP 响应(线程再次阻塞)-> 返回最终结果。在此期间,这个线程不能做任何其他事。

而在 FastAPI 的异步模型中,代码可以写成这样:

from fastapi import FastAPI
import asyncpg
import httpx

app = FastAPI()

@app.get("/data")
async def fetch_data():
    # 异步数据库查询
    conn = await asyncpg.connect(...)
    db_data = await conn.fetch('SELECT * FROM table')
    await conn.close()

    # 异步HTTP请求
    async with httpx.AsyncClient() as client:
        api_data = await client.get('https://external.api/data')

    return {"db": db_data, "api": api_data.json()}

当执行到 await conn.fetch 时,事件循环会挂起这个任务,转而去执行其他已经就绪的任务(比如处理另一个新请求的开始部分)。等数据库返回结果后,事件循环再回来继续执行。这样,单个线程的利用率被极大提升,从而在相同硬件资源下支撑更高的并发连接数。

对于不同类型的服务,性能提升的感知完全不同:

服务类型 Flask (同步 WSGI) 表现 FastAPI (异步 ASGI) 优势
内部管理后台 (低频操作) 完全足够,开发更简单 优势不明显,可能杀鸡用牛刀
AI 模型推理 API (CPU/GPU 密集) 瓶颈在计算,框架影响小 在请求排队、模型加载 I/O 时有优势
数据聚合网关 (高并发 I/O) Worker 数需求大,资源消耗高 并发能力显著提升,资源利用率高
实时通信 (WebSocket) 需要额外扩展,支持较弱 原生支持,开发体验统一

开发体验:从“灵活”到“严谨”的转变

Flask 以其“微”框架的灵活性著称。它只提供最基础的路由和请求/响应封装,数据库用 SQLAlchemy 还是 Peewee,表单验证用 WTForms 还是自己写,文档用 Swagger UI 还是手写 Markdown,全部由开发者决定。这种自由在项目初期或小型团队中是一种优势,但项目规模扩大后,很容易出现风格不一、验证逻辑散落各处的问题。

FastAPI 通过深度集成 PydanticPython 类型提示,引入了一种更“严谨”的开发范式。你通过类型注解来定义请求和响应的数据模型,框架自动完成数据验证、序列化和文档生成。

from pydantic import BaseModel
from fastapi import FastAPI

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float
    tags: list[str] = []

@app.post("/items/")
async def create_item(item: Item) -> Item:
    # 到这里,`item` 已经被验证过,`name`是字符串,`price`是浮点数
    # 你可以直接使用它,无需再写 `if not item.name:` 这样的判断
    return item

这种方式极大地减少了样板代码和运行时错误。更重要的是,它生成的交互式 API 文档(基于 OpenAPI)是实时、准确的,与代码保持同步,对于前后端协作和 API 测试非常有帮助。对于从 Flask 转过来的开发者,初期可能会觉得这种“强制”的类型声明有些繁琐,但一旦适应,会发现它在维护性和开发效率上带来的回报。

选型建议:不是替换,而是场景匹配

所以,是不是所有新项目都应该用 FastAPI,老项目都要从 Flask 迁移过来?当然不是。框架选型始终是权衡的艺术。

坚持使用或选择 Flask 的情况:

  • 快速原型验证:比如一个周末黑客松,你需要最快速度把想法变成可访问的 HTTP 接口。
  • 传统同步业务:业务逻辑本身是线性的,几乎没有并行 I/O 操作,或者 I/O 等待时间极短。
  • 遗留系统与团队技能:团队对 Flask 生态非常熟悉,项目依赖了大量 Flask 特有插件,且当前没有性能瓶颈。
  • 简单的内部工具:预期用户少,并发低,开发速度的优先级远高于运行时性能。

考虑转向 FastAPI 的情况:

  • 新建高并发 API 服务:尤其是微服务架构下的各个服务节点,对吞吐量和响应延迟有明确要求。
  • I/O 密集型应用:服务需要频繁与数据库、缓存、消息队列、其他微服务进行通信。
  • 需要现代 API 特性:如自动文档、WebSocket、GraphQL 订阅等。
  • AI 服务部署:虽然模型推理本身是同步计算,但请求预处理、结果后处理、排队管理、多模型调度等环节常常涉及 I/O,异步架构能更好地管理这些资源。

如果决定迁移:需要注意的坑

如果你有一个运行良好的 Flask 服务,因为性能或新特性决定迁移到 FastAPI,以下几点需要特别注意:

  1. 异步化改造不是简单的 import 替换:核心业务逻辑,特别是数据库操作、HTTP 客户端调用,需要重写为异步版本(使用 async/await 和对应的异步客户端库,如 asyncpg, httpx)。
  2. 小心同步阻塞调用:在异步函数中,如果调用了某个耗时长的同步函数(比如一个没做异步适配的文件读写,或一个计算密集的任务),它会阻塞整个事件循环,抵消异步的优势。这类代码需要放到线程池中运行。
  3. 生态兼容性:检查项目依赖的第三方库是否支持异步。一些 Flask 的知名扩展可能在 FastAPI 中没有直接替代品,需要寻找新的 ASGI 兼容方案或自己实现中间件。
  4. 部署变化:Flask 通常搭配 Gunicorn 同步 worker 部署。FastAPI 推荐使用 Uvicorn、Hypercorn 或 Daphne 这类 ASGI 服务器。部署脚本和监控指标可能需要相应调整。

总结:演进,而非革命

从 Flask 到 FastAPI,反映的是 Python Web 开发对现代应用架构需求的响应。Flask 定义了“微框架”的范式,其简单灵活的设计启迪了一代开发者。FastAPI 则站在巨人的肩膀上,通过拥抱异步编程和类型系统,为构建高性能、可维护的 API 服务提供了新的标准答案。

对于开发者而言,最好的策略不是二选一,而是同时掌握这两种工具。理解 WSGI 和 ASGI 的底层原理,看清同步与异步编程模型的适用边界。这样,在面对下一个项目时,你才能根据真实的业务场景、团队状况和性能要求,做出最合理的架构决策,而不是被技术潮流裹挟。

技术栈的演进很少是断崖式的替换,更多是渐进式的场景适配。今天用 Flask 快速验证的想法,明天可能就需要用 FastAPI 来承载千万级的流量。作为工程师,我们的价值就在于理解这些演进背后的“为什么”,并准备好手中的工具,去应对不断变化的需求。

原创文章,作者:,如若转载,请注明出处:https://fudengji.cn/article/147/

(0)
上一篇 2026年7月31日 上午12:47
下一篇 2026年7月31日 上午12:49

相关推荐