4/4 自动化

16在后台运行 aria2

如果需要一台始终在线的下载服务器,可以启用 RPC 并把 aria2 作为服务运行。在 Linux 上,systemd 用户服务会在登录时启动它,并在它出错退出时自动重启:

~/.config/systemd/user/aria2.service复制

[Unit]

Description=aria2 download server

After=network-online.target

[Service]

ExecStart=/usr/bin/aria2c --conf-path=%h/.aria2/aria2.conf

Restart=on-failure

[Install]

WantedBy=default.target

systemctl --user enable --now aria2复制aria2c -D --conf-path=$HOME/.aria2/aria2.conf复制

第二行是更快捷的替代方案:-D(--daemon)让 aria2 脱离终端,以守护进程方式运行。守护进程会把工作目录切换到 /,因此相对路径会出错:在我们的测试中,-d tmp/x 实际保存到了 /tmp/x。请使用绝对路径。在 NAS 或服务器上,Docker 指南提供了经过测试的容器配置。

17用 JSON-RPC 远程控制

--enable-rpc 会让 aria2 在 6800 端口上作为服务器运行。它支持基于 HTTP 和 WebSocket(ws://host:6800/jsonrpc)的 JSON-RPC,以及 XML-RPC(/rpc)。每次调用都把密钥作为第一个参数传入,写作 token:SECRET。

aria2c --enable-rpc --rpc-secret=s3cret复制curl -s http://localhost:6800/jsonrpc -d '{"jsonrpc":"2.0","id":"1","method":"aria2.getVersion","params":["token:s3cret"]}'复制{"id":"1","jsonrpc":"2.0","result":{"enabledFeatures":["Async DNS","BitTorrent","Firefox3 Cookie","GZip","HTTPS","Message Digest","Metalink","XML-RPC","SFTP"],"version":"1.37.0"}}

添加下载会返回它的 GID,这是一个 16 个字符的 ID,之后的每次调用都要用到它:

curl -s http://localhost:6800/jsonrpc -d '{"jsonrpc":"2.0","id":"1","method":"aria2.addUri","params":["token:s3cret",["https://example.com/file.iso"],{"max-download-limit":"1M"}]}'复制curl -s http://localhost:6800/jsonrpc -d '{"jsonrpc":"2.0","id":"1","method":"aria2.tellActive","params":["token:s3cret",["gid","status","completedLength","downloadSpeed"]]}'复制{"id":"1","jsonrpc":"2.0","result":"54b814f32134da5c"}

{"id":"1","jsonrpc":"2.0","result":[{"completedLength":"1048576","downloadSpeed":"539707","gid":"54b814f32134da5c","status":"active"}]}

密钥错误或缺失时,请求会被拒绝:

curl -s http://localhost:6800/jsonrpc -d '{"jsonrpc":"2.0","id":"1","method":"aria2.getVersion"}'复制{"id":"1","jsonrpc":"2.0","error":{"code":1,"message":"Unauthorized"}}

aria2 1.37.0 共有 33 个 aria2.* 方法,另外还有 system.multicall、system.listMethods 和 system.listNotifications。通过 WebSocket,aria2 还会主动推送六种通知,例如 aria2.onDownloadComplete,因此客户端无需轮询。选项对象中的值都是字符串。如果想不写代码就试一试这些调用,可以使用我们的在线 WebUI。所有方法及真实的请求和回复见 JSON-RPC 指南。

18事件钩子

aria2 可以在下载开始、暂停、停止、完成或出错时运行一个程序,也可以在种子下载完成时(开始做种之前)运行。每条命令会收到三个参数:GID、文件数量和第一个文件的路径。

done.sh复制

#!/bin/sh

echo "$(date) finished $3" >> "$HOME/aria2-done.log"

chmod +x done.sh复制aria2c --on-download-complete=$PWD/done.sh https://example.com/file.iso复制args: 3 | 1=f9bfdbfe450c75f3 | 2=1 | 3=/home/me/out/rand.bin

输出行就是我们的测试钩子收到的内容。请给出脚本的完整路径,并确保它有可执行权限。可用的钩子有 --on-download-start、--on-download-pause、--on-download-stop、--on-download-complete、--on-download-error 和 --on-bt-download-complete。Docker 指南就用了一个钩子来移动下载完成的文件。

19安全与加密

RPC 服务器可以把任何内容下载到你的磁盘上,还能运行钩子脚本,所以请像对待一个有密码保护的管理后台那样对待 6800 端口。务必设置 --rpc-secret;除非可信局域网或 VPN 中的其他设备必须连接,否则不要开启 --rpc-listen-all;永远不要把这个端口转发到互联网。

aria2c --enable-rpc --rpc-secret=$(openssl rand -hex 16)复制aria2c --enable-rpc --rpc-secure --rpc-certificate=cert.pem --rpc-private-key=key.pem --rpc-secret=s3cret复制aria2c --ca-certificate=/etc/ssl/certs/ca-certificates.crt https://example.com/file.iso复制

使用 --rpc-secure 时,aria2 自己通过 TLS 提供 RPC 服务;在我们的测试中,它在 https:// 上应答,并忽略普通 HTTP 请求。另一种做法是使用 nginx 等反向代理。下载时,aria2 会用系统 CA 证书库检查服务器证书;--ca-certificate 可以指定其他证书,--check-certificate=false 则关闭检查,只应对你信任的主机这样做。

20aria2 创建的文件

file.aria2:位于未完成下载旁边的控制文件。下载完成后会被删除。参见 .aria2 文件指南。会话文件(--save-session):未完成的下载及其选项,采用输入文件格式。dht.dat 和 dht6.dat,位于 ~/.aria2/(或 $XDG_CACHE_HOME/aria2/):已知的 DHT 节点,让种子下次更快找到 Peer。Cookie 文件(--save-cookies):Netscape 格式的 Cookie。日志(--log):默认关闭;需要详细信息时使用 --log-level=info 或 debug。.torrent 或 .meta4 文件:只有在你通过 --bt-save-metadata 或 --rpc-save-upload-metadata 要求时才会保存。

21退出码

aria2c 结束时,它的退出码会告诉脚本发生了什么。如果有多个下载,返回的是最后一个错误的退出码。带链接的退出码在故障排查页面上有分步骤的解决方法。

退出码含义

0

所有下载都成功

1

未知错误(连接、TLS 和 RPC 端口错误也用它)

2

超时

3

资源不存在

4

“资源不存在”达到 --max-file-not-found 次数

5

速度过慢:--lowest-speed-limit

6

网络问题

7

aria2 停止时(Ctrl+C)还有未完成的下载

8

服务器不支持续传,但需要续传

9

磁盘空间不足

10

分块大小与 .aria2 文件不同

11

aria2 已在下载同一个文件

12

aria2 已在下载同一个种子

13

文件已存在

14

重命名文件失败

15

无法打开已有文件

16

无法创建或截断文件

17

文件读写错误

18

无法创建目录

19

域名解析失败

20

无法解析 Metalink 文件

21

FTP 命令失败

22

HTTP 响应异常(403、429 也是它)

23

重定向过多

24

HTTP 认证失败

25

无法解析 bencode(.torrent)文件

26

.torrent 文件损坏或不完整

27

磁力链接无效

28

选项或选项值错误

29

服务器暂时过载或维护中(503)

30

无法解析 JSON-RPC 请求

31

保留,未使用

32

校验和验证失败

22单位与实用技巧

大小和速度可以使用 K 和 M,其中 1K 等于 1024 字节。没有 G,也不接受小数;否则 aria2 会以退出码 28 停止:

aria2c --max-download-limit=500K URL复制aria2c --max-download-limit=1.5M URL复制Exception: … errorCode=28 We encountered a problem while processing the option '--max-download-limit'.

-> … Bad or negative value detected: 1.5M

重复设置同一个选项时,最后一个值生效;命令行优先于 aria2.conf。关闭一个开关型选项要写 --name=false,而不是 --name false。--input-file=(留空)可以在单次运行中忽略 aria2.conf 里设置的会话文件。--dry-run 检查 URL 是否可用,而不实际下载。aria2c --help=#http 列出带有某个标签的选项;aria2c --help=split 列出名称中包含某个词的选项。

23面向开发者的 libaria2

aria2 可以编译成 C++ 库(./configure --enable-libaria2),这样程序无需启动 aria2c 或使用 RPC 就能执行下载。API 位于 aria2/aria2.h;每个进程只能有一个会话。下面这个最小程序会下载一个文件:

example.cc复制

#include

int main() {

aria2::libraryInit();

aria2::SessionConfig config;

aria2::Session* session = aria2::sessionNew(aria2::KeyVals(), config);

aria2::addUri(session, nullptr, {"https://example.com/file.iso"}, aria2::KeyVals());

while (aria2::run(session, aria2::RUN_ONCE) == 1) {}

aria2::sessionFinal(session);

aria2::libraryDeinit();

}

g++ -std=c++11 example.cc -laria2 -o example复制./example复制

我们在 Ubuntu 24.04 上针对 libaria2 1.37.0 编译了它,并成功下载了一个 50 MB 的测试文件。aria2 仓库中有两个完整示例:examples/libaria2ex.cc,以及一个 wxWidgets 图形界面程序 libaria2wx.cc。对大多数项目来说,JSON-RPC 更简单,而且可以在任何语言中使用。