为 Go module 搭建私服

IMG-THUMBNAIL

私服还是大势所趋,今天就介绍一个很好用的私服项目 Athens。


之前介绍了如何在线上环境打包,这样能解决问题,但是由于是借助代理下载依赖包,打包的过程偏慢,我自己的感觉打一个项目需要2分钟所有。而且还有一个严重问题,那就是一旦下载失败,打包就失败了,还得重试。这个体验很不好。关于 Go module 打包,我感觉未来的发展方向还是和 Java 的一样,得自己整私服,这样打包会很快,而且也安全。我们打包从私服下载,私服如果缓存了当前版本的包,直接返回;否则私服去下载对应版本的代码。

私服安装

首先你需要安装 Go1.11。

我用的是Athens,雅典娜。

首先下载代码:

  1. git clone https://github.com/gomods/athens
  2. cd athens

即使用私服还是得设置代理:

  1. export HTTP_PROXY=10.244.255.3:7766
  2. export HTTPS_PROXY=10.244.255.3:7766

编译安装二进制文件:

  1. cd cmd/proxy
  2. go install

启动

因为是通过go install安装,所以会被安到$GOBIN里,它会是全局的可以直接调用。

  1. ./proxy

但是这样太简陋了,我用 Supervisor 来做进程守护,配置文件如下:

  1. [program:proxy]
  2. command=/path/to/proxy -config_file=/path/to/github.com/gomods/athens/config.dev.toml
  3. environment=HTTP_PROXY="10.244.255.3:7766",HTTPS_PROXY="10.244.255.3:7766"
  4. stdout_logfile=/tmp/proxy.log
  5. stderr_logfile=/tmp/proxy.log
  6. autostart=true
  7. autorestart=true
  8. startsecs=5
  9. priority=1
  10. stopasgroup=true
  11. illasgroup=true

打包脚本

之前是四行脚本,这次变了两行:

  1. export GO111MODULE=on
  2. export GOPROXY=http://127.0.0.1:3000

打包开始后,私服的日志能看到类似于这样的日志:

  1. handler: GET /github.com/spf13/afero/@v/v1.1.1.zip [200]

而打包日志是这样:

  1. go: downloading github.com/spf13/pflag v1.0.2

如果是第一次下载,会有可能超时:

  1. 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

这样没事,稍等一会就会好,可以把上面的链接放到浏览器里面刷一下,能刷出来结果那说明下载好了。

  1. {
  2. "Version": "v1.0.0-20141024135613-dd632973f1e7",
  3. "Time": "2014-10-24T13:56:13Z"
  4. }

GOPROXY

其实最核心的是上面的GOPROXY,这个是 Go 官方的代理设置,和HTTP_PROXY不一样哦。

可以使用命令go help goproxy查看详细介绍,也可以看这里

Go module 支持通过代理的方式下载,如果环境变量GOPROXY设置了,所有的包都会从这个代理下载。

代理基于 HTTP 协议的 GET 方法,请求的时候没有参数,所以只要是符合固定的规则,任何服务器都可以做代理服务器。比如一个静态文件服务器。

规则是:

GET $GOPROXY/

  1. GET /github.com/mnhkahn/gogogo/@v/list
  2. v1.0.0
  3. v1.0.1
  4. v1.0.2
  5. v1.0.3
  6. v1.0.4
  7. v1.0.5

GET $GOPROXY/

  1. GET /github.com/mnhkahn/gogogo/@v/v1.0.5.info
  2. {
  3. "Version": "v1.0.5",
  4. "Time": "2018-09-26T02:47:43Z"
  5. }

元数据的 Go 结构体定义:

  1. type Info struct {
  2. Version string // version string
  3. Time time.Time // commit time
  4. }

GET $GOPROXY/

  1. GET /github.com/mnhkahn/gogogo/@v/v1.0.5.mod
  2. module github.com/mnhkahn/gogogo
  3.  
  4. require (
  5. github.com/BurntSushi/toml v0.3.0 // indirect
  6. github.com/ChimeraCoder/gojson v1.0.0
  7. github.com/davecgh/go-spew v1.1.1 // indirect
  8. github.com/magiconair/properties v1.8.0
  9. github.com/pmezard/go-difflib v1.0.0 // indirect
  10. github.com/sasbury/mini v0.0.0-20161224193750-64bd399395db
  11. github.com/stretchr/testify v1.2.2
  12. golang.org/x/net v0.0.0-20180826012351-8a410e7b638d
  13. gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3
  14. gopkg.in/yaml.v2 v2.2.1 // indirect
  15. )

GET $GOPROXY/

  1. GET /github.com/mnhkahn/gogogo/@v/v1.0.5.mod
  2. v1.0.5.zip

所有的包名会被编码成小写。如果有大写字母,前面加感叹号。

  1. github.com/Azure => github.com/!azure

Athens 的实现

下载的时候会读取这些环境变量:

  1. func PrepareEnv(gopath string) []string {
  2. pathEnv := fmt.Sprintf("PATH=%s", os.Getenv("PATH"))
  3. httpProxy := fmt.Sprintf("HTTP_PROXY=%s", os.Getenv("HTTP_PROXY"))
  4. httpsProxy := fmt.Sprintf("HTTPS_PROXY=%s", os.Getenv("HTTPS_PROXY"))
  5. noProxy := fmt.Sprintf("NO_PROXY=%s", os.Getenv("NO_PROXY"))
  6. gopathEnv := fmt.Sprintf("GOPATH=%s", gopath)
  7. cacheEnv := fmt.Sprintf("GOCACHE=%s", filepath.Join(gopath, "cache"))
  8. disableCgo := "CGO_ENABLED=0"
  9. enableGoModules := "GO111MODULE=on"
  10. ...
  11. }

HTTP_PROXY和HTTPS_PROXY是私服下载包的时候会用到的代理设置,而NO_PROXY可以加不走代理的白名单:

  1. export NO_PROXY=gopkg.in,$NO_PROXY

这些环境变量会被作为临时环境变量用于代码的下载。而下载依赖包的逻辑:

  1. cmd := exec.Command(goBinaryName, "mod", "download", fullURI)
  2. cmd.Env = PrepareEnv(gopath)
  3. cmd.Dir = repoRoot
  4. o, err := cmd.CombinedOutput()

实际执行时就是:

  1. 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 module 搭建私服,转载请注明来源!

ft_authoradmin  ft_create_time2019-04-26 18:16
 ft_update_time2019-04-26 18:17