内网环境下Go module的包管理和包拉取解决方案

前言

很多开发的小伙伴在工作中经常会遇到需要在内网环境下开发生产,因此就必须要解决内网环境下Go语言的包管理和包拉取问题。恰逢我司前端时间就需要在内网环境下开发新项目,因此在此记录我们内网环境下Go module的包管理和包拉取解决方案,希望给予其他小伙伴有所借鉴。Go 语言在1.16 版本以后已经默认使用 Go Module 模式进行依赖包管理,而Go Module默认使用https://proxy.golang.org作为代理地址来拉取第三方包,但该地址需要能够访问互联网,另外还需要考虑到很多无法直接访问公共的包管理器,如GitHubGolang.orgGopkg.in等。

解决方案

在内网环境下,Go module的包管理和包拉取的常规解决方案主要有以下几种:

  1. 私有代理

在内网中,可以搭建私有的Go module代理服务来缓存、管理和拉取第三方包,以提高包的下载速度,同时解决内网环境下的拉包问题。常用的代理工具有GoproxyAthensNexus等。在搭建好私有代理后,可以设置GOPXOY环境变量来使用私有代理,例如:

highlighter- arduino
$ export GOPROXY = http://172.31.33.33:8080
  1. Vender目录

可以在项目的根目录下创建vendor目录,将依赖的第三方包直接下载到该目录下。在使用go buildgo test等命令时,Go工具链会优先从vendor目录中查找所需的包。在项目根目录下执行以下命令,将当前模块的所有依赖包下载到vendor目录:

highlighter- gams
$ go mod vendor

需要注意的是,endor目录仅适用于项目内的依赖,如果依赖的包又依赖其他第三方包,则需要手动将这些包下载到vendor目录中。同时,如果vendor目录中存在多个版本的同一个包,则需要手动解决冲突。

  1. 将依赖包打包到二进制文件中

可以使用go1.16及以上版本的-embed标志,将项目依赖的第三方包打包到二进制文件中,避免在运行时需要依赖外部的包。该方式适用于将应用程序部署到多个环境中,或将应用程序分发给客户端。

highlighter- pony
$ go build -o app -tags embed -ldflag3="-w -s -extldflags=-static" -embed

以上几个就是在内网中进行Go module包管理和包拉取的解决方案,再结合我们实际开发场景,方案2会导致项目整理越来越大,不利于项目的管理、部署和维护,方案3则是只适合再部署时使用,并不能满足正常的工作开发中的需求场景,因此我们选择方案1,通过内部搭建一个私有的go module代理服务来解决内网环境下的拉包问题。

搭建私有go module代理服务

Go module proxy协议规范发布后,Go社区出现了很多成熟的Goproxy开源实现。从最初的athens,再到国内的两个优秀的开源实现:goproxygoproxy.io等。最终,在考虑到代理服务的部署及维护的方便程度上,我们选择了使用更为简单的goproxygoproxy.io来搭建私有go module代理服务。

代理服务搭建

goproxy搭建

  1. 创建goproxy文件夹,go mod初始化goproxy
highlighter- gams
$ go mod init goproxy
  1. 创建goproxy.go文件,监听本地代理端口,初始化goproxy代理:
highlighter- less
package main

import (
        "net/http"

        "github.com/goproxy/goproxy"
)

func main() {
        http.ListenAndServe("localhost:8080", &goproxy.Goproxy{})
}
  1. 修改GOPROXY环境变量,拉取goproxy服务依赖
highlighter- vim
$ go env -w GOPROXY=https://goproxy.cn,direct
  1. 拉取服务依赖,启动goproxy代理服务:
highlighter- vim
$ cd goproxy
$ go mod tidy
$ go run goproxy.go

goproxy.io搭建

  1. git clone拉取goproxy.io源码:
highlighter- crmsh
$ git clone git@github.com:goproxyio/goproxy.git
  1. 编译goproxy.io/goproxy下的main.go文件
highlighter- powershell
$ cd goproxy.io/goproxy
$ make
  1. 命令行启动代理服务
highlighter- jboss-cli
# 直接启动
$ ./bin/goproxy -listen=0.0.0.0:8088 -cacheDir=./modCache -proxy https://goproxy.cn
# 或者已进程方式后台运行时,命令如下:
$ nohup ./bin/goproxy -listen=0.0.0.0:8088 -cacheDir=./modCache -proxy https://goproxy.cn &

代理服务使用及测试

搭建好私有代理服务后,我们就可以开始使用代理服务拉取第三方包了。使用go module代理服务很简单,通常情况下,我们都是使用对应的IDE工具来进行代码开发,直接在对应的IDE工具中为对应项目配置代理服务地址。以研发环境下GoLand为例,配置如下:

  1. 修改研发机golang环境变量GOPROXYGONOSUMDB
  • 修改GOPROXY环境变量,命令如下:
highlighter- awk
$ go env -w GOPROXY=http://172.31.31.31:2326,direct
  • 修改GONOSUMDB环境变量,命令如下:
highlighter- routeros
$ go env -w GONOSUMDB=*

默认情况下,当我们执行go getgo mod tidy等命令需要下载模块时,它们会将模块版本和校验和发送到sum.golang.org进行验证,以确保安全性和数据完整性。但由于研发机环境无法连接到环境无法连接到sum.golang.org,因此需要跳过模块的校验和(checksum)验证。

而且,我们拉取的是代理服务器本地的缓存包,本来是已经在代理服务器上通过验证了,因此也可以保证其安全性和完成性。

  1. 配置GoLand中的GOPROXY环境变量;

点击Go Module,新增GOPROXY配置项,配置代理服务地址为上述GOPROXY地址。

  1. 在代理服务器上清空本地go module缓存,使用代理服务器重新拉取 GO 模块
highlighter- gams
$ go clean -modcache
$ go mod tidy
  1. 代理服务器拉包完成后,使用研发机拉取代理机上的包缓存即可
highlighter- gams
$ go mod tidy

针对同一个项目,通过分别配置goproxygoproxy.io代理服务地址进行测试,最终我们确定goproxy.io会比goproxy更加稳定一些,goproxy经常会以为网络问题出现部分丢包现象,因此我们确定使用goproxy.io来搭建go module私有代理服务。

需要注意的是:内网环境下通过代理服务器拉取go mod,这种方式需要保证拉取的go mod依赖包与服务器缓存的依赖包版本一致,否则无法拉取依赖。

参考

私有化仓库的 GO 模块使用实践

小厂内部私有Go module拉取方案

goproxy.cn官方文档

goproxy.io官方文档


__EOF__

原创作者: Planet-xx 转载于: https://www.cnblogs.com/Planet-xx/p/18959884
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值