go mod download卡住或OOM需限并发、分批下载并配GOPROXY=direct和GOSUMDB=off;离线机报“no such host”是因未关闭代理与校验,必须显式设置二者;含cgo依赖需提前安装对应C开发库或设CGO_ENABLED=0。

go mod download 会卡住或 OOM,怎么办
go mod download 默认并发拉取所有模块,对内存和网络带宽敏感。资源受限主机(如 1GB RAM 的 ARM 设备、国产轻量云主机)常出现进程被 kill、卡在某个模块不动、或 runtime: out of memory 报错。
关键不是“等它跑完”,而是限制并发和缓冲行为:
- 用
-x参数观察实际下载路径和模块顺序,确认是否卡在某个大包(如github.com/ethereum/go-ethereum) - 加
-v看进度,避免误判为假死 - 强制限流:设置环境变量
GOPROXY=https://goproxy.cn,direct(国内镜像 + fallback),比默认proxy.golang.org更稳定 - 降低并发:Go 1.21+ 支持
GOFLAGS=-toolexec="sh -c 'ulimit -v 300000 && $*'"控制单个工具内存上限,但更直接的是分批下载
推荐做法是先 go list -m all | head -n 50 截前 50 个模块,用 go mod download 逐批执行,每批后 sleep 2 让系统回收内存。
离线机上 go mod download 报 “no such host” 不是没网,是配置漏了
即使已断网,go mod download 仍会尝试解析 proxy.golang.org 和 sum.golang.org —— 这不是 bug,是 Go 默认行为。
必须在离线机上显式关闭两项:
-
go env -w GOPROXY=direct(不是off或空值;direct表示跳过代理,直连本地缓存) -
go env -w GOSUMDB=off(设为off才真正禁用校验;设为空字符串""会 fallback 到默认sum.golang.org)
如果项目含 replace 指向私有 Git 地址(如 git.internal.com/foo),还需加 -mod=readonly 启动参数,否则 go build 仍会尝试解析该域名。
依赖里含 cgo,但离线机没装 libc-dev,build 就挂
go mod download 只管 Go 源码,不检查底层 C 依赖。一旦模块用了 cgo(比如 net 包调 DNS、sqlite3、zlib),离线构建时就会报 cannot find -lc 或 fatal error: sys/socket.h: No such file or directory。
验证方式很简单:go list -f '{{.CgoFiles}}' ./... 查哪些包含 C 文件。常见高危包包括:
github.com/mattn/go-sqlite3-
golang.org/x/net(部分子包启用 cgo 后才支持系统 DNS) github.com/godbus/dbus
应对策略分两层:
- 若允许纯 Go 回退:设
CGO_ENABLED=0,但注意net包将无法读/etc/resolv.conf,DNS 解析可能失效 - 若必须用 cgo:离线机需提前装对应开发库,例如 Ubuntu/Debian 装
libc6-dev、libssl-dev;麒麟/统信系统查apt search dev或用dnf provides */sys/socket.h
vendor 后 go build 仍失败,问题不在 vendor 目录本身
go mod vendor 复制源码到 vendor/,但 Go 构建时仍会读 go.sum 和 $GOPATH/pkg/mod 中的元信息。如果离线机上 go.sum 缺失、哈希不匹配,或 go.mod 里有 // indirect 依赖未被 vendor/modules.txt 覆盖,go build 就会拒绝启动。
真正有效的检查顺序是:
- 运行
go mod verify,看是否报missing hash或mismatch - 对比
go.sum行数和vendor/modules.txt行数,二者应基本一致(modules.txt不含// indirect标记,但所有条目必须在go.sum中存在) - 确认
go env GOMOD指向项目根目录下的go.mod,而不是某层父目录的——路径错会导致模块查找失败
最稳妥的做法是:在联网机上做完 go mod tidy → go mod download → go mod vendor → go mod verify 全部通过,再打包整个项目目录(含 vendor/、go.mod、go.sum)过去。
真正麻烦的从来不是下载动作本身,而是模块元数据与底层系统能力的耦合。一次成功的离线构建,本质是把“联网时能自动补全的东西”,全部变成可验证、可搬运、可落地的确定性文件。











