go mod download 在内网报 connection refused 是因默认直连 proxy.golang.org 和 sum.golang.org,而内网无法访问;根本原因是 GO111MODULE 未启用或 GOPROXY 未生效(如 CI/容器中环境变量未传入),且 GOPROXY 含 direct 会回退外网,应设为纯代理地址并配 GOSUMDB=off。

为什么 go mod download 在内网总是报 connection refused
因为默认行为会直连 proxy.golang.org 和 sum.golang.org,而这两个域名在无外网出口的内网环境中根本不可达。不是 GOPROXY 配置错了,而是它压根没生效——比如你漏写了 GO111MODULE=on,或者 shell 环境变量没传进构建上下文(CI/容器里尤其常见)。
- 确认是否启用模块:运行
go env GO111MODULE,输出必须是on;若为auto,在非 GOPATH 下可能意外退化为 GOPATH 模式,跳过代理逻辑 - 检查 GOPROXY 是否被覆盖:某些 IDE 或构建脚本会临时 unset 它,用
go env GOPROXY实时验证 - 注意
direct的陷阱:GOPROXY 设为https://goproxy.cn,direct时,一旦前一个失败就会 fallback 到 direct,触发外网请求——内网应强制设为https://goproxy.cn(不含,direct)
如何用私有 proxy 代替官方服务
最稳妥的方式是部署一个兼容 Go module proxy 协议的本地服务,比如 athens 或 goproxy。它们能缓存模块、支持离线模式,并绕过 checksum database(sum.golang.org)校验。
- 启动
goproxy简单实例:docker run -d -p 8080:8080 -e GOPROXY=https://proxy.golang.org -e GOSUMDB=off --name goproxy goproxy/goproxy
,然后设GOPROXY=http://localhost:8080 - 关键参数
GOSUMDB=off必须显式关闭校验,否则 go 命令仍会尝试连接sum.golang.org;也可设为sum.golang.org+https://your-intranet-sumdb(需自建 sumdb 服务) - 首次拉取后,所有模块都存在本地 cache,后续构建完全离线;但要注意 vendor 目录不自动更新——
go mod vendor仍依赖 proxy 可用
离线环境下用 go mod vendor 还是 go mod download?
go mod download 是把模块下到 $GOPATH/pkg/mod/cache,供所有项目共享;go mod vendor 是复制一份到当前项目 vendor/ 目录。内网发布时,前者更轻量,后者更可控——但两者都要求依赖已提前下载好。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 推荐组合:在外网机器执行
go mod download -json导出模块列表,再用go mod download <module>@<version>逐个拉取,打包整个$GOPATH/pkg/mod目录同步到内网 - 不要直接拷贝
vendor/:不同 Go 版本对 vendor 处理逻辑有差异(如 Go 1.14+ 默认忽略 vendor),容易导致构建行为不一致 - 验证缓存完整性:
go mod verify在内网运行会失败(因依赖 sumdb),应改用go mod download -json对比哈希值,或用go list -m all确认所有模块路径可 resolve
CI/CD 流水线中 GOPROXY 环境变量失效怎么办
很多 CI 系统(如 GitLab Runner、Jenkins Agent)默认不继承用户 shell 环境,export GOPROXY=... 在本地终端有效,但在 pipeline script 里没作用。
立即学习“go语言免费学习笔记(深入)”;
- 在流水线脚本开头显式设置:
export GOPROXY=https://goproxy.cn<br>export GOSUMDB=off<br>export GO111MODULE=on
- GitLab CI 示例:在
.gitlab-ci.yml中写variables: { GOPROXY: "https://goproxy.cn", GOSUMDB: "off", GO111MODULE: "on" },避免写在script里被子 shell 隔离 - Docker 构建时,用
ARG+ENV传递:ARG GOPROXY="https://goproxy.cn"<br>ENV GOPROXY=${GOPROXY}<br>ENV GOSUMDB=off,注意 ARG 必须在 build stage 显式传入
go 命令执行时,实际走的是你预期的路径,而不是悄悄 fallback 到 direct 或报错后静默忽略。建议在关键节点加 go env | grep -E "(GOPROXY|GOSUMDB|GO111MODULE)" 打印确认。

















