go mod download 在 ci 中卡住的根本原因是默认 proxy.golang.org 国内不可达,需显式配置多源 goproxy(如 https://goproxy.cn,direct)并配合 goprivate、gosumdb=off(临时)及精准缓存 $gomodcache。

go mod download 为什么在 CI 里总卡住
根本原因不是网络差,而是默认 proxy.golang.org 对国内节点无优化,常因 DNS 污染、TLS 握手超时或连接重置失败。CI 环境没人工干预,一旦超时就直接中断,不像本地能反复重试。
- 现象:日志停在
go: downloading github.com/some/pkg v1.2.3不动,超时后报context deadline exceeded - 关键点:
GOPROXY必须显式设置,不能依赖 Go 版本默认值(哪怕 1.16+ 默认开启 Modules,proxy 仍为官方地址) - 错误配置示例:
GOPROXY=https://goproxy.io—— 该服务已停服,返回 502,但 Go 不报错,只静默回退到 direct,导致私有模块也失败
怎么配 GOPROXY 才真正生效
必须用逗号分隔多个代理,并以 direct 收尾,否则私有模块会被错误转发到公共镜像源。
- 推荐配置:
GOPROXY=https://goproxy.cn,direct(阿里云,稳定且校验透传)或GOPROXY=https://mirrors.aliyun.com/goproxy/,direct(路径更规范) - 公司内网场景:加私有代理,如
GOPROXY=https://goproxy.cn,https://nexus.example.com/repository/golang-proxy/,direct - 配套必须设
GOPRIVATE=git.example.com/internal/*,否则 Go 仍会尝试走 proxy 查私有路径 -
GOSUMDB=off是临时调试手段,上线前务必关掉——它绕过 checksum 校验,失去依赖完整性保护
CI 中 go mod download 的执行时机和缓存策略
提前下载本身不耗时,但位置不对就白做;缓存没配对,每次都是从零拉取。
- 执行顺序必须在
go mod tidy之后、go build之前,否则go mod download下载的只是旧依赖列表 - 缓存目录是
$GOMODCACHE(默认$GOPATH/pkg/mod),CI 脚本里要明确缓存该路径,例如 GitLab CI 的cache: paths: [- .go/pkg/mod] - 不要缓存整个
$GOPATH,它包含构建产物和工具,体积大且易污染;只缓存pkg/mod和build/cache - 首次运行前建议加
go clean -modcache清旧缓存,避免因镜像源切换导致 checksum mismatch
go.sum 校验失败的真实原因和应对
报 checksum mismatch 不等于网络问题,大概率是镜像源同步延迟或本地缓存残留。
- 现象:同一 commit,在不同机器上
go mod download成功,但另一台报校验失败 - 优先清缓存:
go clean -modcache,再重试;不是删go.sum,那会破坏锁定 - 确认镜像源是否透传官方 sum ——
goproxy.cn和mirrors.aliyun.com/goproxy都支持,但某些自建 proxy 若没配GOINSECURE或跳过校验,就会出问题 - CI 日志里出现
verifying github.com/xxx@v1.2.3: checksum mismatch时,别急着改go.sum,先检查GOPROXY是否被覆盖(比如被.bashrc里旧配置干扰)
实际跑通的关键,往往卡在 GOPROXY 和 GOPRIVATE 的组合写法是否精确匹配私有模块路径,以及缓存路径是否只针对 pkg/mod —— 其他地方多写一个斜杠或少一个星号,CI 就会默默失效。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











