go mod download 缓存明确存于$GOPATH/pkg/mod(或默认$HOME/go/pkg/mod),含解压源码、符号链接及cache/download下的.zip/.info校验文件,不与GOCACHE混用。

go mod download 缓存到底存在哪?
缓存不是“看不见的黑盒”,而是明确落在 $GOPATH/pkg/mod(或默认 $HOME/go/pkg/mod)下的物理目录。它不依赖 GOCACHE,也不和编译缓存混在一起——go build 用 $GOCACHE,go mod download 只认 pkg/mod。
这个目录里不是直接存 github.com/user/repo@v1.2.3 这样的干净路径,而是:
• 源码解压后实际路径类似 github.com/user/repo@v1.2.3-0.20230101000000-abcdef123456
• 符号链接 github.com/user/repo@v1.2.3 指向它
• 校验文件 .info 和压缩包 .zip 存在 cache/download/ 子目录下,文件名含 checksum
所以别靠 ls | grep 找版本,更别手动 rm -rf 某个看似“干净”的文件夹——破坏符号链接或残留 .info 就会导致后续 go build 报 checksum mismatch。
为什么设置了 GOPROXY 还会反复拉包?
常见错觉是“设了代理就万事大吉”,其实 GOPROXY 只控制下载来源,不保证缓存复用。真正卡住的是缓存路径本身没被复用。
立即学习“go语言免费学习笔记(深入)”;
- CI 环境每次重置
$HOME或未挂载$HOME/go/pkg/mod→ 缓存目录一空,go mod download只能重下 -
go clean -modcache被误加在 CI 脚本开头 → 相当于每次构建都主动废掉缓存 - GOPROXY 配成
https://goproxy.cn却漏了,direct→ 私有模块 fallback 失败,卡在 timeout,看起来像“卡住”而非“没命中” - Go 版本浮动(如 GitHub Actions 用
go@latest)→ 不同 minor 版本对.info格式处理略有差异,旧缓存可能被跳过
验证是否真用了缓存:运行 go mod download -v,看到 cached 字样才说明命中;如果全是 Fetching,说明缓存根本没起作用。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
Docker 构建中怎么让模块缓存真正生效?
Docker 默认不共享宿主机的 pkg/mod,必须显式利用层缓存 + 正确指令顺序,否则每 build 一次都重下所有模块。
关键点只有三个:
- 先
COPY go.mod go.sum .,再RUN go mod download—— 这两行必须紧挨着,且放在COPY . .之前 -
go.mod内容不变时,这一层就永远命中;哪怕源码改了,也不会触发重新下载 - 多阶段构建中,builder 阶段的
/go/pkg/mod不会自动传给 runtime 阶段,但你根本不需要传——runtime 只要二进制,pkg/mod是构建期专属
别信“只 COPY 二进制就行”这种说法:如果 RUN go mod download 写在 COPY . . 后面,那每次改一行代码都会导致整个依赖层失效。顺序错了,缓存就等于没做。
缓存校验失败时该删什么、不该删什么?
go clean -modcache 是安全底线,但它清得太多。真遇到 checksum mismatch 或 unknown revision,优先排查校验源头而不是暴力清空。
先确认这几件事:
-
go env GOSUMDB是不是sum.golang.org?私有代理环境下应设为off或指向内部 sumdb -
go.sum是否提交到 Git?没提交就等于把校验权交给本地缓存,不同人机器上缓存不一致,必然 mismatch - 私有模块是否已配置
go env GOPRIVATE=git.internal.company.com?没设就会走公共 proxy,校验数据对不上 - 磁盘是否写满?
go mod download中断后留下的残缺.zip和空.info是静默故障源
真正要动手删的,往往只是 $GOPATH/pkg/mod/cache/download/ 下某个域名的子目录,或者某次 go mod download -json 显示出错的具体版本路径。全量清理是兜底手段,不是第一反应。

















