Contents
1 前言
由于我的博客采用的是特殊的wordpress双活架构(家庭数据中心中的macmini为主写副读节点,芝加哥Racknerd的VPS为主读节点),所以一旦macmini节点有内容变更(所有博客内容的修改和新文章的发布都在上面完成),就需要通过脚本将macmini节点上mariadb数据库中的wordpress库导出为wordpress.sql文件,并使用scp命令通过与芝加哥节点的ssh连接将该文件传送到芝加哥节点的指定目录中(本来之前用的syncthing基于tailscale IP来同步,但是出境的tailscale基本被废了,所有换成了scp),后续由芝加哥节点上的inotify应用在检测到文件变化之后,自动执行本地脚本完成wordpress库在本地的导入,从而实现两个节点wordpress数据库内容的完全同步。
这个流程之前一直运行得很好,也从没让我我操心过。不过,前几天我忽然发现某些时段运行时出幺蛾子了,scp的状态一直在stalled和ETA之间不停切换,到了20%之后传输速度就越来越慢,一直到最后连接被关闭:

换成rsync同时限制传输的平均速度也不行:

起初我还以为又是 “某wall” 在搞什么骚操作,比如对特定协议或数据模式进行深度检测并重置连接。可后来仔细观察后发现,这个问题与时间段高度相关:每到晚上 23 点之后情况就会变得格外糟糕,而白天则要好很多,很多时候rsync还能顺利传完,如果真是 “某wall” 的影响,按理说不会只在夜里才高发。
继续挖原因,最后终于把元凶锁定在了 Racknerd 的芝加哥节点自身的限制策略上。因为在问题最严重的时段——比如国内晚上 22 点,相当于芝加哥时间上午 9 点,刚好是他们的工作日高峰流量开始;到了国内 23 点,芝加哥正好上午 10 点,也完全符合白领们大规模使用网络的时间段。而反过来看,当国内白天(比如上午 9,10 点)我测试传输时,芝加哥那边往往还是凌晨或夜晚,用网低谷期,限速和丢包都轻得多,不管是用scp还是rsync都有不低的几率能成功传输完文件。
研究了一下,发现这似乎正是很多廉价 VPS 供应商常用的带宽保护手段:他们通常会在机房的网络早高峰(也就是本地工作时间)对单连接(单 TCP 会话)进行流量调度、施加 shaping 或者启用更激进的流量清洗规则,以此保障更多付费客户或整个机房网络的整体可用性。因为这些低价 VPS 本质上就是 oversell(超售),节点带宽远不能满足每台虚拟机都随意跑满,尤其是像 Racknerd 这种以「低价年付」著称的服务商,更常在高峰时段对突发大文件传输直接采取限速、丢包甚至主动 reset 连接来进行压制。
另外,这种限制并不只会发生在 SSH(比如 scp、rsync -e ssh)上传输场景。它实际上是对 单连接长时间持续大流量 的统一策略,以下这些常见情况都很容易中招:
- 使用 scp 或 rsync 通过 SSH 拷贝大文件(典型单 TCP 流,且包持续且稳定)
- FTP passive 或 active 传输单个大文件时同样容易被盯上
- tailscale / zerotier 这种 overlay 网络跑大文件(它们虽然是 UDP,但在出国线路上经常会被当作异常流量处理)
- curl 或 wget 直接下载大文件,也因为单连接持续大带宽很容易触发 shaping
- even 在 Web 上,单个 aria2c 多线程下载往往就能绕开限制,反过来单线程 HTTP GET 就会被限速或掉线
对于 Racknerd 这样的廉价 VPS 服务商而言,这种单连接限速或流量调度几乎不会影响他们的大多数目标客户群体(小型网站、轻量 API、日常运维),只有极少数需要频繁大文件传输或持续跑满带宽的用户会感到头疼。而这,正是他们通过价格与资源控制所默许的”灰色平衡”。
2 解决思路
在遇到这个问题之后,我其实仔细思考了一下,大体上能想到的解决思路主要有三种。
第一种、HTTP/HTTPS服务
首先当然想到的还是最符合互联网直觉的方案:在 macmini 上临时起一个 HTTP 或 HTTPS 服务,然后让芝加哥节点用 aria2c 或 wget -c 这类支持多线程断点续传的工具主动把文件拉过去。毕竟 HTTP 天生就适合文件传输,能轻松搞定分段下载,多线程也能很好地规避 Racknerd 那种对单连接限速的策略。再加上我早就用 Cloudflare Tunnel 把 macmini 的网站安全地暴露到公网,就算已经注销了备案域名,依旧能靠 Tunnel 提供访问服务,根本不用担心国内运营商直接封入向 HTTP 流量的问题。
但转念一想,这么做多少还是有点杀鸡用牛刀。我的场景其实非常简单,无非就是每次传一个不到 100MB 的 SQL 文件,为此还要专门配置多站点目录、增加访问认证、顺带还得考虑 Cloudflare 的缓存规则,反倒显得过于繁琐。而至于 tailscale 或其他基于 WireGuard 的内网穿透工具,就更不适合这种跨境大流量场景了——在我当前这条线路下 tailscale 的稳定性已经不太能指望,大文件经常容易抽风掉线,这种重要任务不敢把宝都押在它身上。
第二种:云端存储中转
就是干脆把文件传到网盘或者对象存储,比如 Google Drive、OneDrive、阿里云 OSS、腾讯 COS 这种地方,再让芝加哥节点从那里下载。这个方法其实非常稳妥,因为这些大厂云的 HTTPS 流量足够”混杂”,就算在 Racknerd 这种廉价 VPS 上,他们的上游运营商也不太敢随意去针对性限速或者丢包处理,从而让下载过程稳得一比。更何况这些对象存储或者网盘天生就支持断点续传、多线程下载,拿 aria2 一跑就完事,传再大的文件都不慌。但换个角度来看,对于我现在这个场景——每周只要传送几次几十兆的 SQL 文件来说,这种方式就显得太大材小用了。上传、再下载,多绕了一圈,平时1分钟能搞定的事非要折腾几个来回,反倒有点”杀鸡用牛刀”,不划算。
第三种:断点续传
这种思路就变成了最适合我的方案:依然使用最简单的 rsync 通过 SSH 单连接传输文件,然后利用 “–partial –append-verify” 的特性在传输中断后继续从断点开始累积传输。结合脚本里加的重试机制,每次失败就等个 10 秒再来一次,最多尝试 5、6 次,几乎就能保证在有限时间内把文件完整地传到芝加哥节点上。这种方式虽然仍旧会被 Racknerd 机房高峰时段的单连接限流策略盯上,但因为文件本来就不大,多次”蚕食”一样地分段传输,反而更容易在实际环境里把事情给做成。说实话,这套方案最大好处就是不需要额外多装什么服务,不用再跑 HTTP 服务器,也不用考虑配置复杂的对象存储,现有的 SSH 能跑就能搞定,既省心也优雅。
所以最后的结论很简单:如果哪天我要传个几百 G 的影视库,那一定老老实实走 COS 或 OSS,再配合多线程下载;要是我只在国外范围传文件,HTTP 肯定香得很;但像现在这样家里 macmini 每周导出几次 50M 的 SQL 文件发到芝加哥 VPS,靠 rsync 断点续传多次累积,真就是最划算的”人间正道”。
注:其实还有一个最省事的办法,就是避开芝加哥白天的流量高峰期,老老实实在其他时段传文件,但是嘛,本着:”有困难要上,没有困难创造困难也要上”的指导思想,当然要直面挑战了,关键是还能水一篇文章~。
3 使用rsync断点续传
3.1 rsync介绍
rsync 是一个在类 Unix 系统(Linux、macOS)上极为常用的文件同步和传输工具。它以高效著称,核心特性就是只传输实际发生变化的文件部分(增量传输),并支持强大的压缩、校验机制,既可以用于本地文件夹之间的备份,也可以通过 SSH 协议在不同服务器之间安全传输文件。
相比于 scp、ftp 这类更”傻瓜式”的传输工具,rsync 的优势在于功能极其丰富,能够在更多场景下做到精准可控:
- 可以在目标端已经存在部分文件时,继续从中断处增量续传(比如通过 –partial + –append-verify),即使网络断了,也能重跑命令从上次进度接着传,非常适合容易丢包、断流的跨国网络。
- 使用 -z 参数可以在传输过程中开启压缩,显著降低跨国链路的带宽消耗,速度通常也会更快。
- 能通过 -a(归档)参数一次性保留文件的时间戳、权限、符号链接等所有元数据,非常适合做精准备份或服务器迁移。
- 加上 –delete 甚至可以让目标目录严格同步为源目录的状态,会把目标中多余的文件直接删除,避免长时间累计垃圾文件。
- 通过 –chown=user:group 可以在同步到目标机器时直接修改文件属主、属组,非常适合像 Web 面板那样需要特定权限的场景,比如用在 iPanel、宝塔等站点目录,让同步后的文件立即可用。
- 加上 –progress 可以显示每个文件的实时传输进度;使用 –bwlimit=2000(单位 KB/s)还能限制最大带宽,避免压满线路。
- 还可以用 –exclude 灵活排除不需要同步的文件,比如 –exclude=.git 或 –exclude=*.log,只同步所需内容。
rsync 也能与 SSH 无缝配合(rsync -e ssh),安全传输同时具备断点续传、增量校验等高级特性,这让它几乎成为跨国服务器备份、站点同步的首选工具。
需要注意的是:rsync 是一个典型的双端工具,它需要在本地和远程机器都安装 rsync,因为远程会通过 ssh 调用自己的 rsync 来参与哈希计算、数据拉取。这也是为什么执行 rsync 时,其实会在 ssh 里隐式调用远程 rsync 的缘故,不需要单独开守护进程或者 FTP 那种专门的服务端口,就能安全传输。也正因如此,rsync 成为了跨国服务器部署、备份、同步脚本里被大量采用的首选工具。
3.2 实现断电续传功能的版本要求
需要注意的是,rsync实现断点续传功能对版本是有要求的(–partial特性几乎所有版本都支持,–append特性需要2.6.4以上版本,–append-verify特性则需要两端的版本在3.x以上),虽然在不少系统中(比如macos、某些发行版的linux)会内置rsync,但是版本却有很大的差异,以我的macos为例,默认为2.6.9,无法支持–append-verify功能:

而芝加哥节点的debian 12中通过apt安装的rsync版本为3.2.3,就能满足断点续传的所有特性:

rsync 最大的亮点之一就是它的「断点续传」能力,这对跨国、易中断的网络环境来说简直是刚需。但它的实现其实分为不同层级,需要通过一些参数来明确告诉它要怎么续传。
1、–partial
这是 rsync 里最基础、最先支持(几乎从最早期 2.x 就有)的参数。
- 作用:如果传输过程中被中断(比如网络闪断,或者手动停止),默认 rsync 会把正在传输的目标文件删掉,避免留下不完整的文件。
- 加上 –partial 后,rsync 会保留这个”残缺文件”,留待下次传输时重新使用。
- 适用版本:所有常见的 rsync(2.x 及以上)都支持。
它其实只是保障「中断后不删文件」,并不意味着下次 rsync 会直接从文件末尾继续上传,而是还会扫描、对比、计算 delta,然后可能重新传某些块。
2、–append
- 从 rsync 2.6.4(2004 年)开始支持。
- 作用:在目标端已经有部分文件时,rsync 会直接从文件末尾追加数据,不做内容校验。
- 适合用在那些只会在文件尾新增的日志类场景,比如不断增长的 log 文件。
缺点是:它不会对已有部分做 hash 校验。如果之前的文件被破坏或者不一致,还是会从尾巴追加,容易导致文件损坏而不自知。
3、–append-verify
- 从 rsync 3.0.0(2008 年)引入。
- 是 –append 的增强版。
- 作用:同样会从目标文件尾开始续传,但在传完之后会对文件做一次校验,确保文件完整无误。如果校验失败,会重新回到传统的”分块比对并传输”流程,确保目标文件和源文件最终一致。
- 非常适合我们这种传输数据库备份、tar 包、SQL 文件等需要严谨一致性的场景。
常用组合: –partial –append-verify
在生产脚本里,大家经常会看到这样写:
rsync -avz --partial --append-verify -e "ssh -p 12345" localfile user@remote:/path/
它们分别扮演的角色:
- –partial 确保如果传输被中断,不会删除已经下载到目标机的部分文件。
- –append-verify 在下次运行时,直接从文件尾巴继续传,传完后还会自动做一次校验,确保文件完整可靠。
这样即便是跨国线路、容易断连,也能通过多次执行 rsync 累计地把文件稳定地传完,不浪费已经传好的数据块。
4 rsync ≠ scp + 断点续传
很多人第一次接触 rsync,往往只是因为需要一个”能断点续传的 scp”。就像我一样,在使用scp跨国文件传输老是失败后,才慌忙去找替代方案,最终被”rsync 支持断点续传”吸引过去,但其实,rsync 远远不止于此,又想起这幅图了:

它不仅能在网络断开后从断点接着同步,还能高效对比源端和目标的文件内容,做到真正的增量传输 —— 哪怕是几百兆的文件,只要只改动了其中几 KB,rsync 就只会传那几 KB 的差异块。这种算法级的优越性,是 scp、ftp 这些简单工具根本做不到的。
以下是同一个时间我使用scp和rsync同时使用相同的链路传送相同wordpress库文件为例进行对比。
scp花了12秒:

rsync只花了4秒:

这还是链路非常好,一次传完的情况下,rsync都只花了scp的3分之1的时间。而如果链路非常糟糕,scp不停重传的情况下,那rsync依靠断点续传简直不知道要快多少。更别说 rsync 还能加压缩、保留文件时间戳和权限、删除目标端多余文件(–delete),甚至通过 –chown 把远端文件的属主直接修改好,让它从文件同步工具直接进阶为部署利器。
它从诞生起就是为”保持两端精确一致”而生的,而断点续传,只不过是它所有能力里最容易被人看见的一角罢了。
5 使用rsync同步目录
5.1 概述
很多人一提到 rsync,想到的就是用它来传输单个大文件(比如本文中的wordpress.sql)。但其实在实际生产和运维场景里,rsync 的最常见用途反而是用来同步目录 —— 比如网站代码、静态资源、备份文件、媒体库、配置文件目录,等等。
5.2 最简单的目录同步
先来看个最常用、最朴素的示例:
rsync -av /local/site/ user@remote:/var/www/site/
这条命令做了什么?
- -a(归档模式)会递归进入子目录,并且保留文件的权限、属主、时间戳、软链接等元数据,相当于 -rlptgoD 的合集,非常适合做备份或部署。
- -v(verbose)显示详细过程。
- /local/site/ 最后的 “/” 非常关键:带” /”表示把目录里的内容同步到远程,而不是把 site 目录本身也同步过去;不带 “/”就会把 site 目录本身也复制过去,变成 /var/www/site/site/。
很多人第一次用会写成:
rsync -av /local/site user@remote:/var/www/
然后发现远程机器多出来了一个 /var/www/site/ 目录,如果只是想把 site 里的文件放到 /var/www/site/,要记得在本地路径后面加 /。
5.3 使用–delete保持严格一致
如果你在做线上部署(比如更新博客或静态站),最常见的还会再加上 –delete:
rsync -av --delete /local/site/ user@remote:/var/www/site/
这表示:让远程目录严格和本地目录保持一致;如果远程目录里多了文件(本地已经删除),rsync 就会帮你删掉它们。适合做一主同步多从、或者对部署一致性要求非常高的场景。
5.4 保证属主、权限一致
在有些 VPS 或生产服务器上,你需要确保属主、属组正确(比如 www-data 或 nginx 用户),这时候可以配合 –chown:
rsync -av --delete --chown=www-data:www-data /local/site/ user@remote:/var/www/site/
这样就不用担心本地用户和远端用户不一样的问题。
5.5 加点压缩,适合跨国线路
如果要跨国同步(比如我从家庭数据中心同步到芝加哥),可以加上 -z,在传输中进行压缩,明显减少带宽消耗,提高速度:
rsync -avz --delete /local/site/ user@remote:/var/www/site/
5.6 小结
所以 rsync 在目录同步场景下的几个常用组合就是:
- -a 保留元信息(权限、时间戳、软链接、属主属组等)
- -v 打印同步过程
- -z 启用压缩,适合跨国
- –delete 让目标目录严格和源一致
- –chown 保证属主属组一致
这也就是为什么,几乎所有网站自动化部署、NAS 同步、备份脚本里,都会用 rsync 来替代 scp、ftp 等工具的原因。
6 在macos上安装最新的rsync
因为芝加哥节点的debian 12安装的rsync版本已经满足要求,就没必要折腾了,我只需要在macmini上使用homebrew安装新版 rsync就行:
brew install rsync
新 rsync 会装在 /opt/homebrew/bin/rsync(Apple Silicon)或 /usr/local/bin/rsync(Intel)。
用以下命令确认rsync的版本:
/opt/homebrew/bin/rsync --version
目前brew安装的rsync最新版是3.4.1:

如果不想每次都用绝对路径(比如 /opt/homebrew/bin/rsync)来调用 Homebrew 安装的新版 rsync,可以通过修改 shell 的环境变量文件 来让它自动生效。
具体做法是:
1、找到你的 ~/.zprofile(Zsh 登录配置文件)或 ~/.zshrc(Zsh 交互式配置文件),用 vim ~/.zprofile 或 open -e ~/.zprofile(或任何编辑器)打开。
2、在文件里添加这样一行,并确保写在文件的最后(避免被后面其它 export 覆盖):
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH"
这行的意思是把 Homebrew 的可执行文件路径放到 $PATH 最前面,这样系统就会优先找到 brew 装的软件,不过千万不要写成下面这样:
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin"
因为这样会把原来的系统路径全部丢掉,导致 ls、cat 这种基本命令都可能失效。
3、修改完保存后,回到终端执行
source ~/.zprofile
hash -r
4、最后用下面的命令检查:
which rsync
rsync --version
确认输出的是 /opt/homebrew/bin/rsync 且版本在 3.4.x,就说明配置成功,以我的macmini为例:


注:debian上安装直接rsync使用apt update && apt install rsync命令即可,我就不单独用一章来写了。
7 使用rsync的断点续传特性基于SSH传送文件
在我的本地家庭数据中心中的macmini和远程芝加哥节点debian12都安装好rsync,同时ssh也正确配置后(推荐先配置好本地到远程SSH的公钥访问,不熟悉的朋友可以参考文章:debian系列 配置ssh公钥登录),就可以直接使用rsync开始传送文件了,先设置导出路径和目标服务器信息如下:
# 设置导出路径,以我要导出的macmini本地的wordpress.sql文件为例:
EXPORT_PATH="/Volumes/data/docker/wordpress/db/wordpress.sql"
# 目标芝加哥vps信息,包括ssh用户名、目标vps的IP地址,ssh端口和远程路径
REMOTE_USER="root"
REMOTE_HOST="107.xx.xx.xx"
REMOTE_PORT="12345"
REMOTE_PATH="/docker/wordpress/db/wordpress.sql"
最终的rsync命令如下:
/opt/homebrew/bin/rsync -az --progress --partial --append-verify -e "ssh -p REMOTE_PORT" "EXPORT_PATH" "REMOTE_USER@REMOTE_HOST:$REMOTE_PATH"
当然,也可以不定义变量直接写,只不过看起来就很长:
/opt/homebrew/bin/rsync -az --progress --partial --append-verify -e "ssh -p 12345" "/Volumes/data/docker/wordpress/db/wordpress.sql" "[email protected]:/docker/wordpress/db/wordpress.sql"
如果传送时报错只需要再次运行命令即可断点续传,反复多次后即可成功完成文件的传送。
8 进阶:使用shell脚本自动重传
手动反复运行命令实现断点续传的方法虽然用起来也毛病,但是从技术角度来说就略low了,偶尔用用还行,要经常这么用肯定会折腾死我,所以最终还是要用到shell脚本了,以下是我使用的脚本内容,供大家参考:
#!/bin/bash
# 加载环境变量(供 ssh 调用时生效)
source ~/.bash_profile
# 设置导出的源路径
EXPORT_PATH="/Volumes/data/docker/wordpress/db/wordpress.sql"
# 目标服务器信息
REMOTE_USER="root"
REMOTE_HOST="107.xx.xx.xx"
REMOTE_PORT="12345"
REMOTE_PATH="/docker/wordpress/db/wordpress.sql.tmp"
FINAL_PATH="/docker/wordpress/db/wordpress.sql"
# rsync 重试配置
MAX_RETRY=10
RETRY_DELAY=10 # 秒
echo "开始导出 WordPress 数据库..."
if docker exec -u root mariaDB01 mysqldump -uroot -pyourpassword --databases wordpress > "EXPORT_PATH"; then
echo "导出成功:EXPORT_PATH"
# rsync 重试循环
COUNT=0
SUCCESS=0
while [[ COUNT -ltMAX_RETRY ]]; do
echo "第 ((COUNT+1)) 次尝试 rsync 传输..."
/opt/homebrew/bin/rsync -az --progress --partial --append-verify -e "ssh -pREMOTE_PORT" "EXPORT_PATH" "REMOTE_USER@REMOTE_HOST:REMOTE_PATH"
if [[ ? -eq 0 ]]; then
echo "rsync 传输成功!"
SUCCESS=1
break
else
echo "rsync 传输失败,等待RETRY_DELAY 秒后重试..."
sleep RETRY_DELAY
((COUNT++))
fi
done
if [[SUCCESS -ne 1 ]]; then
echo "🚨 rsync 多次尝试均失败,退出脚本!"
exit 1
fi
# 远程和本地 md5 校验
echo "🔍 获取远程文件 MD5..."
REMOTE_MD5=(ssh -p "REMOTE_PORT" "REMOTE_USER@REMOTE_HOST" "md5sum REMOTE_PATH | awk '{print \$1}'")
LOCAL_MD5=(/sbin/md5 -q "EXPORT_PATH")
echo "本地 MD5 :LOCAL_MD5"
echo "远程 MD5: REMOTE_MD5"
if [[ "LOCAL_MD5" == "REMOTE_MD5" ]]; then
echo "MD5 校验一致,执行远程改名..."
ssh -p "REMOTE_PORT" "REMOTE_USER@REMOTE_HOST" "mv REMOTE_PATHFINAL_PATH"
# Bark 通知
echo "发送 Bark 通知..."
curl -s --max-time 5 -A "useragent" \
"https://xx.tangwudi.com/myiphone-token/macmini节点通知/wordpress数据库导出成功" >/dev/null
curl -s --max-time 5 -A "useragent" \
"https://xx.tangwudi.com/mymacmini-token/macmini节点通知/wordpress数据库导出成功" >/dev/null
echo "任务完成,所有流程执行成功!"
else
echo "MD5 校验不一致,请检查传输过程!"
exit 1
fi
else
echo "数据库导出失败"
exit 1
fi
echo "脚本结束"
这是一个面向跨国网络不稳定场景特别设计的自动化脚本,用于从本地 Docker 容器中导出 WordPress 的 MariaDB 数据库,并将其备份至位于芝加哥的远程节点,流程如下:
1、首先在本地生成完整的 WordPress库的SQL 文件
2、然后借助 rsync 的断点续传(–partial + –append-verify)机制,在遇到网络波动或被限速导致中断时自动多次重试,最大限度确保传输成功
3、待文件传输完毕后,脚本会在本地与远程分别计算 MD5 哈希值进行严格校验,确认文件内容完全一致
4、再在远程执行一次原子性重命名操作,确保目标服务器上始终只有完整可用的数据库文件
5、所有流程完成后,脚本还会通过 Bark 向手机发送多通道推送通知,让你无需盯着终端就能及时掌握备份结果
整个过程从导出、传输、校验到最终通知全部自动化完成,极大地降低了人工干预的需要,也避免了因跨国线路不稳定带来的潜在数据一致性风险。
9 后话
郁闷的是,当我文章都快写完,正准备用实际案例来验证 rsync 断点续传改造方案的威力时,结果却彻底翻车了 —— 跨境线路忽然变得异常顺畅:传一个 50 多兆的 SQL 文件不但一次就成功,而且速度快得离谱,几乎是瞬间就拉满了带宽,快的时候3秒钟就传完:

我当场都看傻了,还特意在晚上 23:30 以后反复试了好几次,想等那条线路恢复到以往高峰期的拥堵状态,好拍几张典型的”断点续传发挥作用”的图,结果每次都稳如狗,最多不到10秒就结束战斗,速度堪比在国内机房之间传文件,导出脚本也是1次就成功:

这实在太反常了,甚至让我都有点哭笑不得 —— 好不容易折腾出的优化方案,却因为网络状况太好,硬生生没能演示出它最闪光的场景。
不过,冷静下来仔细想想,这也并不算什么玄学现象:跨国网络的不稳定,本来就体现在”不可预测”上,很多时候它并非固定在高峰就必然拥堵,反而常常和一些临时性的路由调度、运营商的 QoS(质量控制)策略有关。比如骨干线路偶尔就会有短暂的带宽释放,或者机房在某些时间段正好没有触发单连接限速阈值,再加上 Cloudflare / HE.net 等中转节点可能临时换了线路,都会导致偶尔出现这种反常的”极速畅通”。
另一方面,也可能和我本地的出口网络临时命中了更优质的回程路径有关。甚至在国际段出口处,某个 peering(互联点)拥堵缓解了,都会瞬间带来传输速度的大幅提升。这也是为什么我们会说”跨国网络从来不是一件可以完全用科学严谨去预期的事”,它始终在多重动态的调度和优先级竞争中。
所以,这次测试刚好碰上了天时地利人和,导致 rsync 优化方案没能在”糟糕场景”下发挥它断点续传的优势,多少有点遗憾,但也从侧面说明:做这些稳健性设计,本来就是为那 20% 不幸碰到最差线路时留的后手,大多数情况下,它反而只是多此一举的保险,等到真正遇到问题而需要的那天,我就不会像之前一样手忙脚乱了。
最近试了syncthing感觉也挺好用,就当是onedrive的平替,用于在我公司和家里nas同步指定文件夹的数据。
只要网络质量没问题,syncthing算是不错的多点直接同步方案了。