go mod download all 在低配主机上易因内存超限卡死或被 oom kill,主因是 go 加载全部模块元信息至内存;应改用分批下载(如 go list -m -json all | jq -r '.path + "@" + .version' | xargs -n 100 go mod download)、启用 gosumdb=off、或改用更轻量的 go get -d -v ./...,并务必通过 go mod verify 验证缓存完整性。

go mod download all 会卡住,不是网络慢,是内存爆了
低配主机(比如 1GB 内存的 ARM 设备或老旧云服务器)执行 go mod download all 容易卡死或 OOM kill,根本原因是 Go 在解析完整模块图时会把所有依赖元信息加载进内存,尤其当项目含大量间接依赖(如 gRPC、Kubernetes client)时,内存峰值轻松超 800MB。
实操建议:
- 改用
go list -m -json all | jq -r '.Path + "@" + .Version' | xargs -n 100 go mod download—— 分批拉取,避免单次内存压顶(需提前装jq) - 跳过测试相关模块:加
-mod=readonly防止go list尝试编译 testdata;或先go mod edit -droprequire golang.org/x/tools等非运行时依赖 - 禁用 checksum 校验缓存:设
GOSUMDB=off,否则每次下载后还要读写go.sum文件,SSD 低速盘上耗时翻倍
go get -d 比 go mod download 更省资源
go get -d 不编译、不校验、不写 go.sum,只下载源码到 $GOPATH/pkg/mod,内存占用通常只有 go mod download 的 1/3~1/2,适合内存紧张场景。
注意点:
- 必须确保
GO111MODULE=on,否则退化为 GOPATH 模式,go get -d会忽略go.mod直接往$GOPATH/src写,后续构建失效 - 加
-v参数可实时看到进度,避免误判“卡住”:go get -d -v ./... - 若项目用了
replace指向本地路径,go get -d会跳过它——这反而是好事,省下本就不该下载的本地模块
离线打包前必须验证缓存完整性
低配机上跑完下载命令,别急着打包。Go 的模块缓存目录($GOPATH/pkg/mod)里可能混入半途失败的模块(比如只下完 @v1.2.0.zip 但没解压),离线后 go build 会报 missing module 或 invalid zip。
验证方法:
- 运行
go mod verify,失败说明缓存损坏(常见于中断后重试) - 检查
$GOPATH/pkg/mod/cache/download下每个子目录是否都有.zip和.zip.hash成对存在 - 用
go list -m -f '{{if not .Indirect}}{{.Path}} {{.Version}}{{end}}' all列出所有直接依赖,再逐个ls $GOPATH/pkg/mod/<path>@<version></version></path>确认目录存在
vendor 不是低配主机的救星,反而更吃资源
有人想用 go mod vendor 把所有依赖塞进项目目录,以为能绕过模块缓存压力。实际在低配机上这是陷阱:
-
go mod vendor本身要遍历全部依赖并复制文件,内存和磁盘 I/O 开销比go mod download更高 - vendor 后
go build -mod=vendor虽不联网,但 Go 仍会扫描整个vendor/目录做 import 分析,小内存设备容易 swap 到卡死 - vendor 目录体积通常是模块缓存的 2~3 倍,1GB 主机可能连解压都失败
真正省资源的做法是:只下载、不 vendor,离线时靠 GOPROXY=off + GOSUMDB=off 直接走缓存,不碰 vendor。











