某台机器要装一个国外的工具,下载速度几十 KB/s,或者干脆卡在 0%。你换了镜像源、重试了十几次、调了超时参数,半小时过去了还是没搞定。
现象
在某台机器上直接下载国外资源很慢,甚至完全下不动。表现为:进度条几乎不动、连接频繁超时、下载到一半断掉。反复重试也没改善。
再仔细看,通常还能观察到几个特征:curl -v 显示 TCP 握手就要花很久;速度曲线时高时低最后归零;错误信息在 timeout、reset by peer、SSL connect error 之间随机跳。这些表现指向的都是同一个事实——链路质量不可控。
这类问题有个特征:它不是"运气不好",怎么重试都不会好。但人在这种情况下容易陷入"再试一次就好了"的循环,尤其是当同一台机器上别的东西都正常的时候。
根因
该机器到目标站点的网络路径不通畅。可能是没有走代理出口、可能是出口线路质量差、也可能是目标站点对该地区的限速——具体原因不重要,重要的是这是环境限制,不是你在被限制的机器上做点什么就能解决的。
理解这一点很关键:调参数、换镜像、重试,都是在症状上打转。真正的变量是"从哪里发出这个请求"。
一个有用的判断标准:如果同一份资源,在一台能正常访问的机器上几秒就下完,而在目标机器上无论怎么试都不行,那问题就百分之百在路径上,而不在"参数"上。
解决
固定套路是:凡是要下载国外的东西,先在能过代理的机器上下好,再传到目标机器。
第一步,在一台有代理出口的机器上完成下载。
# 在这台机器上(假设本地代理监听 7890)
curl -x http://127.0.0.1:7890 -O https://example.com/tools/package.tar.gz
第二步,把文件传到目标机器。
# 直接传
scp package.tar.gz user@目标机器:/tmp/
# 大文件用 rsync,支持断点续传,中断了可以接着来
rsync -P package.tar.gz user@目标机器:/tmp/
第三步,在目标机器上本地安装,不走网络。 这一步常被忽略:很多安装脚本默认还会去联网拉依赖,可以在安装时加"仅本地"的参数(比如 --offline、--no-index),或者提前把依赖一并下好再一起传过去。
如果确实要在目标机器上直接下载,那就给它显式传代理参数——前提是这台机器能连到代理:
curl -x http://<代理地址>:7890 -O https://example.com/package.tar.gz
注意这里的代理地址必须是目标机器能访问到的,不能用 127.0.0.1(除非代理就跑在这台机器上)。这是很多人第一次尝试代理时踩的坑。
延伸与预防
这类"跨网络环境的资源获取"可以固化成一个标准流程,写进团队的运维手册。核心是:不要在被限制的环境里挣扎——识别出"这是环境限制"之后,果断切换策略。
同样的思路适用于很多场景:
- 在国内机器上下载 Docker 镜像(先在某台能通的机器
docker pull再docker save/docker load); - 拉取托管平台上的大仓库(先在能通的机器 clone 再传,或者用镜像站);
- 安装需要联网校验签名的软件包。
判断标准很简单:如果你已经重试了两次以上还是没有改善,就不要再来第三次了,去换条件。 重试适用于"偶发失败",不适用于"环境限制"。把这两者区分开,是省时间的关键。
再补一条工程化的做法:把"下载"和"安装"两步拆开——下载放到能通网络的那台机器,产物放中间位置(本地目录、对象存储、内网文件服务器),安装只做本地操作。这样流水线就不再依赖被限制机器的出网能力,也就不会再被那条慢链路拖住。