起因
跨大洋下载 50 GB 数据集,到一半网断了。重新跑 = 重新下完整 50GB。
HTTP 标准里有 Range header(断点续传),客户端工具不全自动用。
curl:-C - 自动续传
curl -C - -O https://example.com/big.tar.gz
# -C - 让 curl 检测本地文件大小 + Range header 续传
# -O 用 server 提供的文件名保存
如果服务端不支持 Range:
curl: (33) HTTP server doesn't seem to support byte ranges. Cannot resume.
绝大多数现代 HTTP server / CDN 都支持。
加速 / 重试
curl -C - -O \
--retry 5 \
--retry-delay 10 \
--retry-max-time 3600 \
--limit-rate 10M \
-L \
https://example.com/big.tar.gz
--retry 5:网络错误自动重试 5 次--retry-delay 10:间 10 秒--retry-max-time 3600:1 小时内重试--limit-rate 10M:限速 10MB/s(晚上无人时占满带宽,白天礼貌点)-L:跟 redirect
校验
curl -O https://example.com/big.tar.gz
curl -O https://example.com/big.tar.gz.sha256
sha256sum -c big.tar.gz.sha256
下完一定要校验,网络可能让文件损坏。
wget:默认更友好
wget -c https://example.com/big.tar.gz
# -c 续传
加重试 / 限速:
wget -c \
--tries=10 \
--retry-connrefused \
--waitretry=30 \
--limit-rate=10m \
--user-agent='Mozilla/5.0' \
https://example.com/big.tar.gz
镜像整个目录:
wget -r -np -nH --cut-dirs=2 -R 'index.html*' \
https://example.com/files/2024/
-r递归-np不向上跳目录-nH不创建 host name 目录--cut-dirs=2砍掉前 2 级路径-R 'index.html*'排除目录列表 HTML
aria2c:多连接 + magnet + 元数据 vacuum
sudo apt install aria2
brew install aria2
aria2c -x 16 -s 16 https://example.com/big.tar.gz
# -x 16: 同一服务器最多 16 个连接
# -s 16: 同一文件用 16 个 segment 并行下
如果服务端支持 Range,多个 TCP 连接并行下不同字节范围,
吃满带宽(单 TCP 流由于 congestion control 经常吃不满)。
速度通常 3-5x 单连接。
更激进:
aria2c -x 16 -s 16 -j 4 -k 1M --file-allocation=falloc \
--max-tries=10 --retry-wait=30 \
https://example.com/big.tar.gz
-j 4: 同时下 4 个文件-k 1M: 每 segment 至少 1MB--file-allocation=falloc: ext4/xfs 上预分配文件(防碎片)
aria2c 支持的协议
# HTTPS
aria2c https://...
# FTP
aria2c ftp://user:pass@host/path
# BitTorrent
aria2c some.torrent
# Magnet link
aria2c 'magnet:?xt=urn:btih:...'
# metalink (含多个 mirror)
aria2c file.metalink
下大文件 magnet 时 aria2c 远比传统 BT 客户端轻量。
多 mirror
aria2c \
https://us.mirror.example.com/big.tar.gz \
https://eu.mirror.example.com/big.tar.gz \
https://asia.mirror.example.com/big.tar.gz
3 个 mirror 同时下,每个用不同 segment。
带宽利用最大化。
续传
aria2 默认自动续传:
aria2c https://example.com/big.tar.gz
# 中断 → 再跑同命令,从断点继续
断点信息在 .aria2 控制文件里。
rsync:对增量传输最优
rsync -avz --progress --partial \
user@server:/path/to/big.tar.gz \
./big.tar.gz
--partial:保留部分传输的文件供下次续传--progress:显示进度条- rsync 还能传整个目录树 + 只传差异,比 scp 强 10x
更激进的限速 / 加密:
rsync -avz --bwlimit=10000 \
-e 'ssh -c [email protected]' \
src/ dst:/path/
--bwlimit=10000 = 10 MB/s。aes128-gcm 加密快(用现代 CPU 的 AES-NI),
比默认 ChaCha20 快 2-3 倍。
边下边校验:sha256 + tee
curl -L https://example.com/big.tar.gz | tee big.tar.gz | sha256sum -
# 边下载 + 边写文件 + 边算 hash
# 输出 hash 后对比 expected
适合一次性下 + 校验场景。
限速 + 后台 + 续传完整组合
# 启动一个后台下载
nohup aria2c -x 8 -s 8 --max-overall-download-limit=20M \
--enable-rpc=true --rpc-listen-all=true --rpc-secret=mysecret \
-d ~/Downloads -o big.tar.gz \
https://example.com/big.tar.gz \
> ~/Downloads/aria2.log 2>&1 &
# 通过 RPC 控制(暂停 / 看进度)
curl -s -d '{"jsonrpc":"2.0","method":"aria2.tellActive","id":"x","params":["token:mysecret"]}' \
http://localhost:6800/jsonrpc | jq
aria2 RPC 让你用 web UI(aria2-webui)控制。Synology / OpenMediaVault
等 NAS 都有 aria2 GUI 包。
服务端:让你的文件支持 Range
nginx:
location /downloads/ {
alias /var/www/downloads/;
# 默认 nginx 静态文件就支持 Range,不需要配
}
应用程序自己 stream 大文件时(如 Django/FastAPI/Flask),要手动处理
Range header。或者直接让 nginx 服务静态文件(最快)。
反过来:让别人能续传我的下载
# FastAPI 例
from fastapi import FastAPI, Request, Response
from fastapi.responses import StreamingResponse, FileResponse
import os
@app.get('/download/{filename}')
def download(filename: str, request: Request):
path = f'/var/files/{filename}'
# FileResponse 自动处理 Range
return FileResponse(path, filename=filename)
FileResponse / nginx X-Sendfile 都支持 Range。
自己写 stream generator 要:
- 看
Range: bytes=100-200header - 返回 206 Partial Content +
Content-Range
效果
跨太平洋下 50GB(实测):
| 工具 | 时间 | 带宽利用 | 注意 |
|---|---|---|---|
| curl | 6h | 25% | 单 TCP |
| wget -c | 6h | 25% | 同上 |
| aria2c -x 8 | 1.5h | 95% | 8 并行 |
| aria2c + 3 mirror | 45min | 100% | 3 mirror × 8 段 |
| rsync | 7h | 22% | SSH 加密开销 |
中断续传都 OK,但 aria2c 显著快。
踩过的坑
-
服务端不支持 Range → curl
-C -直接报错。
测试:curl -I -H "Range: bytes=0-100" https://...,
返回206 Partial Content= 支持。 -
proxy / CDN 不传 Range → 一些反代默认 buffer,吞 Range header。
nginx 加proxy_set_header Range $http_range;。 -
aria2c segment 上限:每个 segment 一个 TCP 连接,过多反而
慢(拥塞 + 服务端 ratelimit)。8-16 是甜点。 -
文件名含特殊字符 / 编码:URL encode 不完整时下错文件。
curl -o "myname.tar.gz" -L url显式指定本地名。 -
磁盘满 silent fail:下载到 99% 磁盘满 → 文件损坏。
df -h提前确认空间。
登录后参与评论。