bigywater.tech
Flask · 140

Flask 与 ASGI

Flask 是 WSGI 框架,放到 uvicorn 这类 ASGI 服务器上有什么用?吞吐量会变好吗?能不能因此支持 WebSocket?这篇用真实的 ApacheBench 压测与 WebSocket 握手,把这两个问题的答案量出来。

3213 / 5992
轻量接口 /hello 的请求/秒:gunicorn sync×4 与 uvicorn×4 加 a2wsgi(单次测量)
403
对 Flask 经 WSGI 适配器暴露的路径发 WebSocket 握手得到的状态码
失败 0
全部压测请求都成功

四种部署的压测

实测 · 本机执行输出
  [轻量接口 /hello]
     gunicorn sync × 4 个 worker(WSGI)                 3213 请求/秒 | 平均   10.0 ms(32 并发)| p99 26 ms | 失败 0
     gunicorn gthread × 4 个 worker × 4 线程(WSGI)       3335 请求/秒 | 平均    9.6 ms(32 并发)| p99 23 ms | 失败 0
     uvicorn × 4 个进程 + a2wsgi(ASGI)                   5992 请求/秒 | 平均    5.3 ms(32 并发)| p99 11 ms | 失败 0
     uvicorn × 4 个进程 + asgiref WsgiToAsgi(ASGI)       3343 请求/秒 | 平均    9.6 ms(32 并发)| p99 25 ms | 失败 0
  [有点计算的接口 /work(2 万次乘加)]
     gunicorn sync × 4 个 worker(WSGI)                 2797 请求/秒 | 平均   11.4 ms(32 并发)| p99 23 ms | 失败 0
     gunicorn gthread × 4 个 worker × 4 线程(WSGI)       2592 请求/秒 | 平均   12.3 ms(32 并发)| p99 23 ms | 失败 0
     uvicorn × 4 个进程 + a2wsgi(ASGI)                   2861 请求/秒 | 平均   11.2 ms(32 并发)| p99 27 ms | 失败 0
     uvicorn × 4 个进程 + asgiref WsgiToAsgi(ASGI)       2898 请求/秒 | 平均   11.0 ms(32 并发)| p99 25 ms | 失败 0

上一篇:同步代码阻塞异步请求;下一篇:WSGI 到 ASGI 的适配。

压测工具是系统自带的 ApacheBench,与被测服务同机运行,每个数字只测一次。

WebSocket

实测 · 本机执行输出
  对 /ws 发 WebSocket 握手 → WebSocketBadStatusException: Handshake status 403 None -+-+- {'content-length': '0'} -+-+- None
  同一路径的普通 HTTP GET → 200 plain http route

分步演示

Flask 与 ASGI
本步的对象

    本文用到的工具与边界

    • 本机 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,数字每次运行会有小幅抖动。uvicorn 0.54.0、gunicorn、a2wsgi 1.10.10、asgiref 3.12.1、ApacheBench
    • 没有验证:多次重复测量的方差、keep-alive 开启时的数字、HTTP/2、生产环境的反向代理叠加、Quart 等原生异步 Flask 兼容框架、更长时间的稳定性
    京ICP备2026067502号-1京公网安备11010502063487号