为 Go module 搭建私服

589dgd · · 97 次点击 · · 开始浏览    
私服还是大势所,今天就介绍一个很好用的私服项目雅典。 私服安装 启动 打包脚本 GOPROXY GET $ GOPROXY // @ v / list返回所有已知的当前模块的版本号,每行一条 GET $ GOPROXY // @ V /.info返回JSON格式的版本元数据 GET $ GOPROXY // @ V /.mod返回这个模块版本的go.mod文件 GET $ GOPROXY // @ V /.zip返回这个模块对应版本的zip压缩包。 雅典的实现 介绍之前了如何用英语上环境打包,这样能解决问题,但是由于是借助代理下载依赖包,打包的过程偏慢,我自己的感觉打一个项目需要2分钟所有。而且还有一个严重问题,那就是一旦下载失败,打包就失败了,还得重试。这个体验很不好。关于Go模块打包,我感觉未来的发展方向还是和Java的一样,得自己整私服,这样打包会很快,而且也安全我们打包从私服下载,私服如果缓存了当前版本的包,直接返回;否则私服去下载对应版本的代码。 私服安装 首先你需要安装Go1.11。 我用的是雅典,雅典娜。 首先下载代码: git clone https://github.com/gomods/athens cd athens 即使用私服还是得设置代理: export HTTP_PROXY=10.244.255.3:7766 export HTTPS_PROXY=10.244.255.3:7766 编译安装二进制文件: cd cmd/proxy go install 启动 的英文因为通过go install安装,会所以安被到$GOBIN里,它会是全局的可以直接调用。 ./proxy 但是这样太简陋了,我用主管来做进程守护,配置文件如下: [program:proxy] command=/path/to/proxy -config_file=/path/to/github.com/gomods/athens/config.dev.toml environment=HTTP_PROXY="10.244.255.3:7766",HTTPS_PROXY="10.244.255.3:7766" stdout_logfile=/tmp/proxy.log stderr_logfile=/tmp/proxy.log autostart=true autorestart=true startsecs=5 priority=1 stopasgroup=true illasgroup=true 打包脚本 之前是四行脚本,这次变了两行: export GO111MODULE=on export GOPROXY=http://127.0.0.1:3000 打包开始后,私服的日志能看到类似于这样的日志: handler: GET /github.com/spf13/afero/@v/v1.1.1.zip [200] 而打包日志是这样: go: downloading github.com/spf13/pflag v1.0.2 如果是第一次下载,会有可能超时: go: gopkg.in/tomb.v1@v1.0.0-20141024135613-dd632973f1e7: unexpected status (http://10.244.255.3:7766/gopkg.in/tomb.v1/@v/v1.0.0-20141024135613-dd632973f1e7.info): 500 Internal Server Error 这样没事,稍等一会就会好,可以把上面的链接放到浏览器里面刷一下,能刷出来结果那说明下载好了。 { "Version": "v1.0.0-20141024135613-dd632973f1e7", "Time": "2014-10-24T13:56:13Z" } GOPROXY 其实最核心的是上面的GOPROXY,这个是Go官方的代理设置,和HTTP_PROXY不一样哦。 使用可以命令go help goproxy查看详细介绍,可以也。看这里。 Go module支持通过代理的方式下载,如果环境变量GOPROXY设置了,所有的包都会从这个代理下载。 代理基于HTTP协议的GET方法,请求的时候没有参数,所以只要是符合固定的规则,任何服务器都可以做代理服务器。比如一个静态文件服务器。 规则是: GET $ GOPROXY // @ v / list返回所有已知的当前模块的版本号,每行一条 GET /github.com/mnhkahn/gogogo/@v/list v1.0.0 v1.0.1 v1.0.2 v1.0.3 v1.0.4 v1.0.5 GET $ GOPROXY // @ V /.info返回JSON格式的版本元数据 GET /github.com/mnhkahn/gogogo/@v/v1.0.5.info { "Version": "v1.0.5", "Time": "2018-09-26T02:47:43Z" } 元数据的Go结构体定义: type Info struct { Version string // version string Time time.Time // commit time } GET $ GOPROXY // @ V /.mod返回这个模块版本的go.mod文件 GET /github.com/mnhkahn/gogogo/@v/v1.0.5.mod module github.com/mnhkahn/gogogo require ( github.com/BurntSushi/toml v0.3.0 // indirect github.com/ChimeraCoder/gojson v1.0.0 github.com/davecgh/go-spew v1.1.1 // indirect github.com/magiconair/properties v1.8.0 github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sasbury/mini v0.0.0-20161224193750-64bd399395db github.com/stretchr/testify v1.2.2 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3 gopkg.in/yaml.v2 v2.2.1 // indirect ) GET $ GOPROXY // @ V /.zip返回这个模块对应版本的zip压缩包。 GET /github.com/mnhkahn/gogogo/@v/v1.0.5.mod v1.0.5.zip 所有的包名会被编码成小写。如果有大写字母,前面加感叹号。 github.com/Azure => github.com/!azure 雅典的实现 下载的时候会读取这些环境变量: func PrepareEnv(gopath string) []string { pathEnv := fmt.Sprintf("PATH=%s", os.Getenv("PATH")) httpProxy := fmt.Sprintf("HTTP_PROXY=%s", os.Getenv("HTTP_PROXY")) httpsProxy := fmt.Sprintf("HTTPS_PROXY=%s", os.Getenv("HTTPS_PROXY")) noProxy := fmt.Sprintf("NO_PROXY=%s", os.Getenv("NO_PROXY")) gopathEnv := fmt.Sprintf("GOPATH=%s", gopath) cacheEnv := fmt.Sprintf("GOCACHE=%s", filepath.Join(gopath, "cache")) disableCgo := "CGO_ENABLED=0" enableGoModules := "GO111MODULE=on" ... } HTTP_PROXY状语从句:HTTPS_PROXY的英文私服下载包的时候会用到的代理设置,而NO_PROXY可以加不走代理的白名单: export NO_PROXY=gopkg.in,$NO_PROXY 。这些环境变量会被作为临时环境变量用于代码的下载而下载依赖包的逻辑: cmd := exec.Command(goBinaryName, "mod", "download", fullURI) cmd.Env = PrepareEnv(gopath) cmd.Dir = repoRoot o, err := cmd.CombinedOutput() 实际执行时就是: HTTP_PROXY=10.244.255.3:7766 HTTPS_PROXY=10.244.255.3:7766 GOPATH=/tmp/athens167327692 GOCACHE=/tmp/athens167327692/cache go mod download golang.org/x/text@v0.3.0

入群交流(和以上内容无关):Go中文网 QQ 交流群:798786647 或加微信入微信群:274768166 备注:入群;关注公众号:Go语言中文网

97 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传