选 Flask 更合适多数场景;它成熟稳定、调试友好、Windows 支持完整,配合 gevent 可支撑几百 QPS;Sanic 仅在多路并行 I/O(如并发调用多个 HTTP 接口+Redis)时才有优势,但要求全链路异步且团队熟悉 asyncio。

选 Flask 还是 Sanic,取决于你有没有真正需要异步处理的 I/O 场景。没有阻塞型 I/O(比如数据库查询、HTTP 调用、文件读写),强行上 Sanic 不但没收益,反而增加调试和部署复杂度。
Flask 什么时候够用?
多数内部工具、管理后台、低并发 API、原型验证项目,Flask 完全胜任。它不强制你写 async/await,也不要求你理解事件循环——这反而是优势。
- 路由、模板、蓝图、扩展生态(
Flask-SQLAlchemy、Flask-Login)成熟稳定,文档和社区支持远超 Sanic - 配合
gunicorn --worker-class gevent,在中等并发(几百 QPS)下表现足够好,且无需重写业务逻辑 - 调试友好:断点、
print、logging行为符合直觉;Sanic 的异步上下文容易让日志时间戳错乱、变量作用域难追踪 - Windows 开发支持完整;Sanic 官方明确不支持 Windows(截至 2026 年仍无原生适配)
Sanic 真正发挥价值的场景
不是“用了 async 就更快”,而是当你的请求路径里存在多个可并行的 I/O 操作时,Sanic 才能摊薄等待时间。典型如:同时调用三个外部 HTTP 接口 + 查一次 Redis + 写一条日志。
- 必须用
async函数处理请求,所有依赖库也得支持异步(比如asyncpg、httpx、redis-py的 async 版本),否则会意外阻塞整个 event loop -
app.run(fast=True)启用多进程后,每个 worker 是独立的 asyncio event loop,不能直接共享内存状态(比如全局 dict 缓存),需改用asyncio.Queue或外部存储 - 路由匹配性能极高(微秒级),但只在路由数 > 1k 时才有感知;小项目里这点差异被网络延迟完全掩盖
迁移 Flask 到 Sanic 的常见陷阱
语法像 Flask,但执行模型完全不同。照搬代码大概率出问题。
立即学习“Python免费学习笔记(深入)”;
-
request.args、request.json在 Sanic 里是协程,必须await request.json(),否则返回的是 coroutine 对象而非 dict - 中间件函数必须声明为
async def,且await下游 handler,漏掉await会导致响应空或超时 -
app.add_route注册的函数签名必须带request参数;Flask 允许无参视图,Sanic 不允许 - 测试时别用
test_client.get()直接调,要用app.test_client.get(..., gather_request=False)避免 event loop 冲突
真正卡住人的从来不是框架选型,而是团队对 asyncio 的熟悉程度和上下游服务的异步兼容性。一个没写过 asyncio.gather 的人,硬上 Sanic,三天内大概率写出伪异步代码——表面用了 async,实际还是串行 await,性能比 Flask 还差。


















