2026-09-12-上传任务队列5并发.md

上传任务队列(类迅雷:5 并发 + 其余自动等待)


一、已实现的行为

特性说明
并发上限 5同时最多 5 个文件在传;其余进入等待队列,有空位自动补位(不是按分块,是按任务)
等待状态可见等待中的文件行显示 ⬜ 文件名 — 等待中…,并随队列推进自动补位
任务汇总条上传区下方实时显示:任务 45 个(并发上限 5):进行中 5 · 等待中 32 · 已完成 3 · 已跳过 8 · 失败 1
逐行状态图标⬜ 等待中 / 🔍 检查中 / ⬆️ 上传中(带百分比与块序号) / ⏭️ 已跳过 / ✅ 完成 / ❌ 失败
不再自动刷新全部结束后不再自动 reload(否则刚出的结果看不到),改为在汇总条上给出 🔄 刷新文件列表 按钮
可调并发数服务端环境变量 DL_UP_PARALLEL(默认 5,范围 1~20),注入页面 window.__UP_PARALLEL__;改后重启服务生效

二、为什么这样更好(与旧行为对比)

旧版(45 个文件一起发起)新版(5 并发 + 等待队列)
浏览器连接使用45 个文件的分块请求抢 6 条连接,FIFO 轮转,每个文件每轮只推进 1 块5 个文件各占 1 条连接顺序传自己的分块,另 1 条连接留给状态查询
文件完成观感所有文件齐头并进(长期都卡在 20~26 块),要到队尾才集中完成逐个完成,看得见进度
失败影响面一个文件失败会占住连接槽、拖累整体观感单个文件失败只影响自己,立刻腾出名额给等待任务
服务端压力几十个会话同时写盘、集中合并最多 5 路写盘 + 合并闸门(2 路),负载平稳

三、生效方式(重要)

  1. 服务已重启(22:4x):新前端已上线,同时把上一轮发现的 io_uring SQPOLL 空转修复一并生效 ——
    • UV_USE_IO_URING=0 + UV_THREADPOOL_SIZE=8;
    • 实测新进程 iou-sqp 线程数 = 0(此前该线程独占 54.5% 单核,占进程 CPU 的 82%);
    • 压测:640MB 分块上传+合并 1.1s(约 600MB/s,本机环回),进程总 CPU 约 1.7 核,说明关掉 io_uring 毫无性能损失。
  2. 你需要刷新上传页面(浏览器里还是旧 JS),然后重新选择 models 文件夹:
    • 已完整落盘的 13 个模型会秒跳(⏭️);
    • 45 个未完成文件从断点继续(约 67GB 已收数据全部保留,不会重传);
    • 之后就是「5 个在传 + 其余等待中」的迅雷式队列。
  3. ⚠️ 重启瞬间有 12 个文件的分块请求被中断(chilloutmix、anything-v5、Anything-V3-pruned、cetusMix-v3.5、canistermix4_v11、nekorayxl_v06W3、aiceKawaice_channel、CounterfeitV30_v30、CounterfeitV30_v30-pruned、final-prune-fp16、AbyssOrangeMix2_sfw、SDXLPixelArtBeta_beta),页面上这些行会显示 ❌ —— 重新选择后自动续传,进度不丢。

四、调参与回滚

# /etc/systemd/system/dl-server.service
Environment=DL_UP_PARALLEL=5      # 改成 3 / 8 等即可;改完 systemctl daemon-reload && systemctl restart dl-server
Environment=UV_USE_IO_URING=0     # io_uring SQPOLL 空转修复(若需 io_uring 可删除本行)
Environment=UV_THREADPOOL_SIZE=8

回滚前端队列逻辑:cp ~/Downloads/download-server.js.bak-20260912-214503 ~/Downloads/download-server.js 后重启(注意备份里没有今天后续的其它修复,仅作参考)。

五、验证记录

六、相关文件

七、附:22:33 的一次自动重启(原因未定论)+ 新增日志留痕

事件:22:32:27 我手动重启(部署队列 + io_uring 修复)后,22:33:26 systemd 又自动重启了一次(NRestarts=1,ExecMainStartTimestamp=22:33:26),被替换的进程只活了约 50 秒。

排查结论:未能定论。已排除:

影响:Restart=always 在约 50 秒内自动拉起,上传未中断(监控采样显示字节数持续增长)。

改进(已上线) —— 针对「无时间戳、退出无痕迹」这两个导致无法定论的根本缺陷:

  1. 日志加时间戳:每行形如 [2026/9/12 22:38:08] ...,时间线可直接对账;
  2. 启动留痕:[start] pid=… node=… io_uring=关闭 上传并发上限=5 合并并发=2;
  3. 退出留痕:捕获 SIGTERM/SIGINT/SIGHUP 与 exit,打印 [exit] 进程退出 code=… pid=…(SIGKILL 无法捕获,但 systemd 会记 Main process exited, code=killed)。

下次再发生同类事件,可直接从日志时间戳与退出码定位,而不是靠推测。

下载此文件