Flask 发大文件该怎么发?send_file 与整个读进内存、手写生成器差多少?断点续传支持吗?让 nginx 来发文件有什么好处?这篇用 300 MiB 的文件、真实的 gunicorn 与 nginx 把答案量出来。
send_file(sendfile) 200 用时 0.07 秒 | 速度 4375 MB/s | 收到 315 MB | worker 空闲内存 64 MB,下载期间峰值 68 MB 整个文件读进内存再返回 200 用时 0.12 秒 | 速度 2528 MB/s | 收到 315 MB | worker 空闲内存 65 MB,下载期间峰值 368 MB 64 KB 一块的生成器 200 用时 0.11 秒 | 速度 2774 MB/s | 收到 315 MB | worker 空闲内存 65 MB,下载期间峰值 68 MB
上一篇:缓存命中率;下一篇:压测下的全局状态问题。
文件在本机页缓存里,没有磁盘读取的限制,速度数字偏高,只看相对关系。
状态行: HTTP/1.1 206 PARTIAL CONTENT | Content-Range: bytes 313524224-314572799/314572800 | Content-Length: 1048576 | Accept-Ranges: bytes | ETag: True 带 If-None-Match 的再次请求 → 304 (304,不再传文件)
经 nginx 代理 Flask 的 send_file 200 用时 0.97 秒 | 325 MB/s | 收到 315 MB | gunicorn 日志里这个请求占用 worker 170 ms X-Accel-Redirect 让 nginx 直接发文件 200 用时 0.94 秒 | 334 MB/s | 收到 315 MB | gunicorn 日志里这个请求占用 worker 2 ms
nginx 是自己起的实例(自签证书),internal location 用 alias 指向文件所在目录。