真正卡住的是模块校验阶段和代理 fallback 逻辑,而非依赖树深度;当 sum.golang.org 不可达时,go 会无超时重试所有 goproxy 链路,导致 verifying 阶段长时间阻塞。

依赖树过深本身不会导致 Go 模块下载变慢,真正卡住的是模块校验(verifying)阶段和代理 fallback 逻辑——尤其当某层间接依赖的 checksum 无法从 sum.golang.org 获取时,Go 会逐个重试所有 GOPROXY 链路,形成指数级等待。
go mod download 卡在 verifying github.com/xxx@v1.2.3 是什么问题
这不是下载慢,是校验阻塞。Go 在下载每个模块后,必须向 sum.golang.org 查询其哈希值并本地比对;该服务在国内不可达,且 Go 默认不设 timeout,会卡住几十秒甚至更久,直到超时后才尝试下一个 proxy。
- 现象:日志停在
verifying github.com/some/pkg@v0.5.1,Ctrl+C 无效,几秒后才继续 - 原因:Go 工具链用纯 Go DNS + 无 timeout 的
net.Dial去连sum.golang.org,中间任意环节丢包或 DNS 慢都会放大延迟 - 验证方式:运行
go mod download -x github.com/some/pkg@v0.5.1,看最后是否卡在GET https://sum.golang.org/lookup/...
GOPROXY=https://goproxy.cn,direct 为什么仍校验失败
goproxy.cn 本身透传 sum.golang.org 记录,但它不能解决“Go 主动去连 sum.golang.org”这个行为。只要 GOSUMDB 没关或没换源,校验阶段仍会直连官方校验库。
- 必须配套设置:
go env -w GOSUMDB=off(仅开发环境)或go env -w GOSUMDB=sum.golang.org+replace=gosum.io(生产可用) - 漏掉
,direct会导致私有模块 fallback 失败,但不会影响校验卡顿;真正拖慢深度依赖的是校验环节,不是代理链本身 - 某些老版本 Go(如 1.18 之前)对
GOSUMDB=off支持不完整,建议升级到 Go 1.21+
依赖树超过 5 层后下载时间翻倍?别信这个说法
Go 不会递归解析整个树再开始下载。它按需拉取、并行 fetch,并缓存已验证模块。所谓“越深越慢”,其实是间接依赖中混入了未被镜像收录的冷门模块(比如刚发布的 v0.x.y),或某层依赖指定了 replace/exclude 导致校验路径异常。
- 检查冷门模块:运行
go list -m all | grep -E "(github.com|gitlab.com)/[^/]+/[^/]+" | head -20,看是否有非常规路径 - 禁用 replace 干扰:临时注释
go.mod中所有replace行,再go mod tidy,观察是否恢复 - 跳过 vendor 干扰:若项目含
vendor/目录,Go 可能绕过 GOPROXY,加-mod=readonly强制走模块模式
真正要盯住的只有三点:GOPROXY 是否带 ,direct、GOSUMDB 是否被正确覆盖、go env GO111MODULE 是否为 on。其他诸如“清理缓存”“换镜像站”“调低并发数”,对深度依赖场景基本无效——问题不在下载管道,而在校验握手那一次失败的 dial。











