bigywater.tech
Flask · 137

Flask Async View

Flask 支持 async def 视图,它到底带来了什么?每个请求是不是都在同一个事件循环里?在 gunicorn 下能同时处理更多请求吗?这篇用真实的 asyncio 与 gunicorn 把边界量出来。

1.51 → 0.5 秒
请求内三个各 0.5 秒的等待:依次 await 与 asyncio.gather
+251 µs
async 视图相对 sync 视图每个请求多出的耗时
8072 秒
gunicorn sync 单 worker 下 8 个并发 async 视图的总耗时(没有变快)

事件循环与请求内并发

实测 · 本机执行输出
  GET /s → sync | GET /a → async
  两个请求里事件循环的 id 相同吗: False | 线程相同吗: False | 视图里能用 request.path: /loop
  一个请求里:asyncio.gather 三个各 0.5 秒的等待 → 0.5 秒;依次 await 三次 → 1.51 秒

上一篇:Flask 同步请求模型;下一篇:Async View 的执行边界。

额外开销

实测 · 本机执行输出
  sync 视图 69 µs/请求;async 视图(await 一个 sleep(0))320 µs/请求;多出约 251 µs

WSGI 下的并发

实测 · 本机执行输出
  gunicorn sync,1 个 worker               async 视图 8.07 秒 | sync 视图 8.04 秒 | 全部 200:True
  gunicorn gthread,1 个 worker × 8 线程     async 视图 1.03 秒 | sync 视图 1.02 秒 | 全部 200:True

分步演示

Flask Async View
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动。asgiref 3.12.1、gunicorn sync 与 gthread worker
    • 没有验证:在 ASGI 服务器(uvicorn、hypercorn)下运行同样的视图(见第 140 篇)、异步数据库驱动、async 视图里调用阻塞代码的后果(见第 139 篇)、before_request 等钩子写成 async 的行为
    京ICP备2026067502号-1京公网安备11010502063487号