FrankenPHP 1.2 大文件上传中断本质是请求未完整送达即被拦截,主因有三:max_memory_upload混合缓冲导致解析卡死、Nginx client_max_body_size提前返回413、缺乏分片容错机制;需分层解决——设FRANKENPHP_MAX_MEMORY_UPLOAD=0强制落盘、Nginx配client_max_body_size 2G并重载、启用专用worker分离上传通道、前端切片+后端Redis记录进度实现断点续传。

FrankenPHP 1.2 上传大文件中断,本质不是“连接被断”,而是请求未完整送达服务端就被拦截或终止。常见原因集中在三处:PHP 层缓冲策略、Web 层(Nginx)提前拒绝、以及上传过程缺乏分片容错能力。解决需分层处理,不靠单点调参。
关闭 max_memory_upload 避免内存卡死
FrankenPHP 默认对 ≤2MB 文件全载入内存,大文件则前 2MB 在内存、其余落盘——这种混合模式极易在 multipart 解析阶段卡住或超时。 - 设环境变量 FRANKENPHP_MAX_MEMORY_UPLOAD=0,强制所有上传一律落盘 - 同步确保 upload_max_filesize 和 post_max_size 足够(如 2G),且两者都生效(Docker 中用 environment,systemd 中写 Environment=) - 不要依赖file_get_contents($_FILES['file']['tmp_name']),改用 fopen + fread(8192) 流式读,或直接 move_uploaded_file() 转移临时文件
绕过 Nginx 的 client_max_body_size 拦截
即使 FrankenPHP 和 PHP 配置都调大了,Nginx 默认只允许 1MB 请求体,会在请求抵达 PHP 前就返回 413。 - 在 Nginx 配置的http、server 或对应 location 块中添加:
client_max_body_size 2G;
- 若使用 fastcgi 协议(如反代到 FrankenPHP CLI 模式),还需检查:
fastcgi_buffer_size 128k;fastcgi_buffers 8 128k;
nginx -t && nginx -s reload 生效,仅重启 FrankenPHP 无效
用 Worker 分离上传通道防拖慢主接口
大文件上传耗时长、占资源多,若走主路由会阻塞其他轻量请求。 - 在frankenphp.yaml 中定义专用上传 Worker:
worker {
file /path/to/upload_handler.php
num 4
env UPLOAD_TMP_DIR /mnt/ssd/uploads/
}
- 前端必须将上传请求发往 /frankenphp-worker(FrankenPHP 自动挂载路径),而非 /api/upload 等主路由
- num 4 表示开 4 个独立线程处理上传,避免抢占主应用资源
- 强制 UPLOAD_TMP_DIR 指向高速磁盘,规避 /tmp inode 或 I/O 瓶颈
前端必须切片 + 服务端记录进度
HTTP 本身不支持断点续传,中断后重传只能靠前后端协同设计。 - 前端用File.slice() 切块(建议每片 5–10MB),每片携带:
-
upload_id(UUID,首次上传时由后端生成并存 Redis) -
chunk_index和total_chunks -
file_md5(可选,用于秒传或合并校验)
/chunks/{upload_id}/{index}.bin,同时更新 Redis 中该 upload_id 的已收分片列表
- 上传前先发 HEAD 请求查进度,决定从哪一片开始传;失败后仅重传缺失分片
不复杂但容易忽略



















