Repository navigation
GitPort GitHub v0.5.0
GitPort GitHub v0.5.0
相对 v0.4.3:镜像链从「静态链序串行」改成「按请求动态分派」。以前填 8 个镜像等于 1 个在用、7 个备胎;现在 8 个能同时干活。
⚡ 大文件在线下载:多镜像终于有意义了
以前每条链是串行的——同一时刻只有一家在服务,其余的只在失败时才顶上。多填镜像的唯一用处是「坏一个换一个」。
现在每个分片请求单独选家:ECT =(该镜像在途未交付字节 + 本次请求字节)÷ 实测速度,取预计最早下完的那家。
- 忙但快的镜像照样可能赢;快镜像在途堆到一定程度,公式自己会改选空闲的那家
- 下载器开几个线程,代理就把这几个分片摊给几家不同镜像——填了几家用几家
- 没有测速样本时统一假设 2MB/s,退化为「选在途最少」,再退化为链序,冷启动不用等校准
- 只填一家镜像的用户,行为与旧版逐字节一致
本机实测(IDM,163MB 的 release 包):48 个 Range 分片,13 秒下完(约 12.5MB/s),8 条镜像链全部用上,零镜像失败、零掐断,最终 zip 校验完好。
🎯 垃圾镜像不再拖后腿:显著性检验掐断
判据是「跟同组同伴比」,不是绝对水位——绝对阈值在全员都慢的时候会误杀。
- 每 128KB 评估一次,流速率 < 同伴中位数 ÷ 20 判为显著离群 → 断流,交下载器重发;重发请求自动重新选家
- 同伴必须在 30s 内有速度样本且至少 3 个;全员低速的窗口里谁也不比谁慢 20 倍 → 零误杀
- 每链每 60s 最多掐 4 次,掐满就放行(宁可慢,不自残)
- 无 Range 的流永不掐——浏览器单线程直接下载,掐断就是用户可见的失败
- 掐断瞬间把慢速率强制写进速度表(直接覆盖旧印象,不做平滑),下次派发不会再派回它
📦 plans.json 拆成两个字典
mirrors_big(codeload / objects / release-assets)与 mirrors_small(raw / gist / avatars / user-images / media)。
两类资源体质不一样:大文件拼持续吞吐,小文件拼头延迟,分开管才不会互相污染。
- 分类权在 host 上:条目放错字典,启动时也会被归位,不会出错
- 旧的单字典
mirrors照常读入、按 host 归位,下一次落盘自动转双字典,一条不丢(plans.json.bak兜底仍在) - github.com 自己的镜像链除名(内容域 9 → 8):那条链在生产路径上根本走不到,
/archive与/releases/download早已归属 codeload / release-assets 专属链
🔧 校准瘦身:大文件不再做合成测速
- 退役大文件吞吐校准(5MB × N 家并发,白烧公益镜像带宽,测出来的也不是真实下载速度):大文件域的速度改由真实流量 EWMA 持续学习
- 保留图片链 TTFB 校准(那是头延迟,真实流量学不到);WebUI 只留图片链按钮,并注明大文件无需校准
✅ 响应校验补洞
- 带 Range 的请求必须回 206:镜像不认 Range 回 200 = 把整个文件灌回来 = 断流,判失败换家
- 304 无正文直接放行(顺带修掉 304 带 content-type 被误判成假站的老问题)
🧵 该配哪个下载器
浏览器自己下载是单线程、不带 Range,代理没法给它分片——所以这套优化只对支持多线程分片的下载器生效,也正因为如此,代理永远不会掐断浏览器的下载。
推荐 IDM / Motrix / MotrixNext 这类,线程数开大一些才有意义:线程数就是同时使用几家镜像的上限。理论上镜像越多、并发上限越高,但这是公式推出来的,没做上限实测,别当承诺。
验证:95 项测试通过,release 构建零警告。
升级提示:无需手改配置。旧 plans.json 的单字典 mirrors 会在启动时按 host 自动并入 mirrors_big / mirrors_small,下次落盘即完成转换。