为什么要在自己的服务器上搭一个离线下载服务
做站久了总会遇到这样的场景:需要从国外某个源站拉一个几个 G 的系统镜像或者数据集,本地宽带跑满也要几个小时,中间断一次就得重来;或者手头有一台挂着大带宽的 VPS,白天基本闲置,晚上想让它帮你把一堆链接慢慢下好,第二天再拖回本地。这类需求的核心其实不是"下载",而是"把下载这件事挪到一台 7×24 小时在线、网络稳定、能断点续传的服务器上",也就是常说的离线下载(offline download)。
很多人第一反应是装个带图形界面的下载器,但在纯 SSH 的服务器上跑 GUI 既不现实也不优雅。真正适合服务器场景的方案是 aria2:一个用 C++ 写的命令行多协议下载工具,支持 HTTP/HTTPS、FTP、SFTP、BitTorrent 和 Metalink,特点是多连接分片、断点续传、内存占用低,配合 AriaNg 这个纯前端页面,就能得到一个和"带界面的下载器"体验几乎一样的 Remote 管理后台。本文把这套东西从零搭一遍,重点讲清楚配置文件里那些参数到底在管什么,以及实际会踩的坑。
aria2 的三种运行形态与选型
动手前先理清一个容易混淆的点:aria2 本身没有守护进程模式,它只是一个命令行程序。所谓"服务化"是靠三种方式实现的,选错了后面会很难受。
- 一次性任务:
aria2c "https://example.com/file.iso",下完就退出。适合临时拉一个文件,不适合长期挂着。 - RPC 模式:
aria2c --enable-rpc --rpc-listen-all=false,aria2 常驻并监听一个 JSON-RPC 端口,AriaNg 或其他前端通过这个端口提交任务、查询进度。这是我们要的形态。 - systemd 服务:把 RPC 模式包成一个 systemd unit,实现开机自启、崩溃自动重启、日志归集。生产环境必须这么做。
结论:RPC 模式 + systemd 守护 + AriaNg 前端。下面按这个顺序搭。
第一步:安装 aria2
Debian/Ubuntu 直接装发行版包最省事,版本通常在 1.36 以上,功能完全够用:
apt update
apt install -y aria2
# 确认版本与编译特性,BitTorrent、Metalink 是否开启一眼可见
aria2c --version | head -20输出里的 Enabled Features 一行会列出 BitTorrent、Metalink、Async DNS 等。如果打算下 BT 种子,必须确认 BitTorrent 在列表里;某些精简发行版的包会把它裁掉,这时需要从源码编译或者找第三方源。
第二步:写配置文件,逐项讲清参数含义
aria2 的配置放在 ~/.aria2/aria2.conf 或 /etc/aria2/aria2.conf。建议每行都写注释,因为过几个月回头看,你一定不记得 --max-connection-per-server=16 当初为什么是 16。下面是一份经过实战的配置,逐段解释:
# ==== 基础 ====
# 下载目录,注意必须是绝对路径且运行用户有写权限
dir=/data/downloads
# 单个文件最大并行连接数(对 HTTP/FTP 有效)
# 对同一台服务器,8~16 是性价比区间;再高对端往往会限速或封 IP
max-connection-per-server=16
# 一个文件最少切成多大才启用多连接
# 太小的文件切了反而更慢,1M 是个稳妥值
min-split-size=1M
# 单个任务最大并发下载数(任务之间的并行度,不是单文件连接数)
max-concurrent-downloads=5
# 断点续传:默认开启,配合 .aria2 控制文件
continue=true
# ==== RPC ====
enable-rpc=true
rpc-listen-all=false
rpc-listen-port=6800
# 令牌必须设置!否则任何能访问该端口的人都能控制你的下载器
rpc-secret=换成你自己的长随机串
rpc-allow-origin-all=true
# ==== 磁盘与文件 ====
file-allocation=falloc
# 预分配用 falloc(fallocate 系统调用,瞬间完成,仅 ext4/xfs/btrfs 支持)
# 老文件系统或网络盘用 none,否则可能报 "fallocate failed"
auto-file-renaming=true
# 同名文件自动改名,避免覆盖
allow-overwrite=false
# ==== 重试与超时 ====
max-tries=5
retry-wait=10
timeout=60
connect-timeout=15
# ==== BT/PT 相关(不下种子可整段注释)====
bt-enable-lpd=true
bt-max-peers=64
bt-request-peer-speed-limit=100K
enable-dht=true
dht-listen-port=6881-6999
seed-time=0
# seed-time=0 表示下载完立刻做种 0 分钟,即不做种,适合纯下载场景几个最关键的取舍讲透:
max-connection-per-server 不是越大越好。 它是"对同一台服务器开几条 TCP 连接去抢同一个文件"。很多站点会针对单 IP 做连接数限制,开太大会被直接 reset;而 CDN 场景下每条连接可能落在不同的边缘节点,开到 16 反而能显著提速。经验值:对 GitHub Release、SourceForge 这类走 CDN 的,开到 16;对普通自建 Apache/Nginx 站点,8 就够。
file-allocation 决定启动那一刻卡不卡。 三种取值:none 不预分配,边下边写;prealloc 直接往前写零填充,大文件时会卡住几秒到几十秒;falloc 调用 fallocate(2) 瞬间占位。SSD + ext4/xfs 无脑选 falloc。如果下载目录挂在 NFS 或老 ext3 上,falloc 会失败并报错,此时退回 none。
rpc-secret 是安全底线。 你的配置文件里如果只开了端口不设令牌,任何扫到你 6800 端口的人都能通过 JSON-RPC 让你去下载任意文件、把磁盘写满、甚至借助 aria2 的 --on-download-complete 执行命令。务必设一个足够长的随机串,并且用防火墙把 6800 端口限制在必要来源。
第三步:systemd 服务化
新建 /etc/systemd/system/aria2.service:
[Unit]
Description=aria2 JSON-RPC daemon
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
# 强烈建议用专用低权限用户,而不是 root
User=aria2
Group=aria2
ExecStart=/usr/bin/aria2c --conf-path=/etc/aria2/aria2.conf
Restart=on-failure
RestartSec=5
# 允许文件描述符多一点,连接数高时会用到
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target准备用户和目录,然后启动:
useradd -r -s /usr/sbin/nologin aria2
mkdir -p /data/downloads /etc/aria2
chown -R aria2:aria2 /data/downloads
systemctl daemon-reload
systemctl enable --now aria2
systemctl status aria2 --no-pager
# 看端口有没有起来
ss -lntp | grep 6800第四步:用 AriaNg 当前端
AriaNg 是纯静态的单页应用,不需要后端,把它的静态文件丢给 Nginx 或者任意目录即可。最省事的做法是用 Docker 起一个,或者直接下载发布包解压到站点目录:
# 方式一:直接下载 release(AriaNg 官方从 GitHub 发布)
cd /var/www
wget https://github.com/mayswind/AriaNg/releases/download/1.3.7/AriaNg-1.3.7-AllInOne.zip
unzip -o AriaNg-1.3.7-AllInOne.zip -d ariang
# 方式二:Docker
docker run -d --name ariang -p 127.0.0.1:6880:80 \
--restart=always hurlenko/aria2-ariang然后用 Nginx 反代并且加一层 HTTP Basic 认证,因为 AriaNg 本身没有登录功能——任何能打开它的人只要能连到你的 aria2 RPC 就能操作:
server {
listen 443 ssl http2;
server_name dl.example.com;
ssl_certificate /etc/letsencrypt/live/dl.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dl.example.com/privkey.pem;
location / {
auth_basic "restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
root /var/www/ariang;
index index.html;
}
# 只反代 RPC,不对外暴露 6800
location /jsonrpc {
auth_basic "restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://127.0.0.1:6800/jsonrpc;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
生成密码文件:htpasswd -c /etc/nginx/.htpasswd admin。打开 AriaNg 后在"设置 → RPC"里填入 https://dl.example.com/jsonrpc 和你在 aria2.conf 里设的 rpc-secret,连接状态变绿即成功。
实战:用 JSON-RPC 直接提交任务(无前端也能用)
有时候你不想开浏览器,想在脚本里直接丢链接给 aria2,那就直接打 JSON-RPC。这是排查"前端连不上"最有效的办法,因为它绕过了所有前端环节:
# 提交一个下载任务,注意 secret 前缀 token:
curl -s http://127.0.0.1:6800/jsonrpc \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "aria2.addUri",
"params": [
"token:你的rpc-secret",
["https://example.com/bigfile.iso"],
{"dir": "/data/downloads", "split": "16", "max-connection-per-server": "16"}
]
}'
# 查询所有活动任务
curl -s http://127.0.0.1:6800/jsonrpc \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":"1","method":"aria2.tellActive","params":["token:你的rpc-secret"]}'addUri 返回任务 GID,后续所有操作(暂停 aria2.pause、继续 aria2.unpause、查询状态 aria2.tellStatus)都用这个 GID。这个方法的价值在于:当 AriaNg 报"连接失败"时,先用 curl 打一次 RPC,如果 curl 通而前端不通,问题一定在反代或跨域;如果 curl 也不通,问题在 aria2 服务本身。
常见坑位与排查
- 下载目录写入失败、任务秒变 error: 90% 是权限问题。aria2 以
aria2用户运行,但/data/downloads属主还是 root。chown -R aria2:aria2 /data/downloads解决。用journalctl -u aria2 -n 50能看到明确的Permission denied。 - fallocate failed: 下载目录在 NFS、overlayfs、老 ext3 上时
falloc不支持,配置改回file-allocation=none。 - RPC 页面打不开但服务在跑: 先
ss -lntp | grep 6800确认监听在 127.0.0.1(rpc-listen-all=false时只监听本地,这是刻意的安全设置),再确认 Nginx 反代的是/jsonrpc而不是根路径。 - BT 下载没有速度: 检查
dht-listen-port和listen-port对应的 UDP/TCP 端口是否被防火墙挡住。BT 依赖大量入站连接,端口不通速度会断崖式下跌。 - 下了半天发现同名文件被覆盖: 确认
allow-overwrite=false且auto-file-renaming=true,两者一起才安全。 - 磁盘被写满导致全站故障: 离线下载是典型的"能把磁盘吃干"的服务。务必给下载分区单独设置配额,或写一个 cron 定期清理已完成任务的文件。别和高优先级业务共用同一分区。
一个实用补充:下载完成后自动通知
aria2 支持在任务完成时执行钩子脚本,这对"下好了再拖回本地"很有用:
# 在 aria2.conf 里加:
on-download-complete=/usr/local/bin/aria2-notify.sh
# aria2-notify.sh:
#!/bin/bash
# $1 = GID, $2 = 文件数量, $3 = 第一个文件路径
curl -s -X POST https://api.telegram.org/bot<你的token>/sendMessage \
-d chat_id=<你的id> \
-d text="下载完成: $3"小结
把 aria2 用好的关键不在装,而在三件事:用 systemd 把它变成可靠的服务、用 rpc-secret + 防火墙守住控制端口、把它和业务数据分区隔离。参数层面记住三组:max-connection-per-server 管单文件速度上限、max-concurrent-downloads 管任务并发、file-allocation 管启动瞬间是否卡顿。调好之后,你会得到一个挂在服务器上、断电重启能自愈、手机浏览器都能随时提交任务的下载后台,它省下的手动重试时间,远比搭它的那半小时值钱。