go mod download 卡住的根本原因是默认代理 proxy.golang.org 国内连接不稳定,需设 GOPROXY=https://goproxy.cn,direct 并确保环境变量生效,避免 DNS 干扰和 fallback 失败。

为什么 go mod download 总是慢到卡住
根本原因不是 Go 本身慢,而是默认从官方 proxy.golang.org 拉包,国内直连不稳定,DNS 污染、TLS 握手超时、连接复用失败都会触发重试+退避,看起来像“卡住”。真实现象常是:go mod download 卡在某个模块几秒不动,然后报 Get "https://proxy.golang.org/...": dial tcp: i/o timeout。
解决思路不是换镜像站就完事,得让 Go 工具链明确知道“别碰国外地址”,且避免本地 DNS 干扰:
- 必须设
GOPROXY环境变量(不是仅改go env -w),推荐值:https://goproxy.cn,direct或https://goproxy.io,direct - 加
,direct是关键:对私有模块(如公司内网 Git 地址)自动 fallback 到直连,不走代理 - 如果公司用了自建 Nexus/Artifactory,把它的 Go 代理地址放最前,例如:
http://nexus.example.com/repository/goproxy/,https://goproxy.cn,direct - 别信某些教程说“改
go env -w GOPROXY=...就够了”——Shell 启动新进程时若没继承环境变量,go命令仍会读空值
七牛云 goproxy.cn 的实际表现和坑点
goproxy.cn 是七牛云维护的公开 Go 代理,缓存全量模块,但要注意它不是“加速器”,而是镜像服务。速度取决于你机器到七牛节点的网络质量,不是所有地区都快。
常见问题:
立即学习“go语言免费学习笔记(深入)”;
- 偶尔出现
404 Not Found错误,尤其对刚发布的模块(比如v1.2.3发布后 1–2 分钟内),因为 CDN 缓存未刷新,此时等几分钟或临时切https://goproxy.io - 不支持私有模块认证——如果你的
go.mod里写了replace example.com/internal => git@git.example.com/internal v0.0.0-20230101000000-abc123,而该 Git 服务器需要 SSH key 或 HTTP Basic Auth,goproxy.cn无法帮你鉴权,必须靠,directfallback - 它不处理
go get -insecure,也不支持 http 协议源(Go 1.13+ 默认禁用 http)
如何验证代理是否生效且没被绕过
别只看 go env GOPROXY 输出,那只是配置项;真正要确认的是 Go 命令运行时实际请求了哪个地址。
方法很简单:
- 执行
go mod download -x github.com/gin-gonic/gin@v1.9.1(加-x开启调试日志) - 观察输出里是否出现类似
GET https://goproxy.cn/github.com/gin-gonic/gin/@v/v1.9.1.info的请求行 - 如果看到
GET https://proxy.golang.org/...或直接git clone,说明GOPROXY没生效,或模块被replace/exclude规则绕过了 - 顺手检查
GOINSECURE和GONOSUMDB是否误设——它们会让 Go 跳过代理和校验,容易误以为“变快了”,实则是关掉了安全机制
CI/CD 环境下必须显式设置代理
Docker 构建、GitHub Actions、GitLab CI 默认不继承宿主机环境变量,go mod download 很可能又回到慢速直连状态。
实操要点:
- Dockerfile 中写死:
ENV GOPROXY=https://goproxy.cn,direct,别依赖构建参数传入 - GitHub Actions 在
steps里加:env: { GOPROXY: 'https://goproxy.cn,direct' } - GitLab CI 在
.gitlab-ci.yml的variables:下加GOPROXY: "https://goproxy.cn,direct" - 注意引号:YAML 里带逗号的字符串必须加双引号,否则解析失败,导致
GOPROXY变成空值
模块缓存本身不解决首次下载慢的问题,但代理能避免反复失败重试。真正影响体验的,往往是那个没被注意到的、漏掉的环境变量。










