Goproxy.cn 核心代码探究;https://github.com/goproxy/goproxy 开源模块分析;


文章背景:

之前曾写过《》一文;在文中,我提到了环境变量的GOPROXY的配置。国内,因为存在着防火墙的原因,很多国外的网站都需要特殊渠道访问。

然而,我们在go开发的时候,需要依赖国外很多服务来进行辅助开发,如各种开源的go模块。从GO1.11开始,其支持模块;并且推出代理的方式,使得我们可以通过代理的形式,来进行获取我们所需要的服务。

一些常用的go代理见链接:Are there "always on" module repositories and enterprise proxies? 

我在上述教程中,使用的是 goproxy.cn,当然也可以选择使用其他服务,只要可用即可。goproxy.cn 在七牛云环境上进行部署,并通过其CDN服务进行加速,整体使用感受上还是比较快速的。

最近,刚刚通过了硕士论文答辩,等待毕业,暂时没有忙别的事情,就抽出了一些时间,初步看了一下goproxy.cn的代码。下面对阅读后的想法进行简要记录:

主要参考链接:

goproxy代码仓库:https://github.com/goproxy/goproxy

goproxy模块文档:https://pkg.go.dev/github.com/goproxy/goproxy

goproxy服务主页:https://goproxy.cn/

模块分析:

goproxy 模块整体思路还是比较简单的。通过阅读其源码可以发现:其主体由goproxy.Goproxy构成;并通过Cacher和Cache两个接口,对接多种底层存储,如磁盘,对象存储等。其通过实现mod.go、sumdb_client_ops.go实现回源和代理请求。并且实现一些相关工具函数,辅助http处理。为实现与go命令对接,其实现了官方的 Go's module proxy protocol,并且通过实现 http.Handler 接口来支持http服务,支持get等方法;

因为GO模块是基于版本设计,所以可以认为时一旦生成即不可变动的数据形式,即数据流只存在带向数据流动;所以goproxy.cn服务不存在缓存一致性问题,因此整体实现上难度简单;只要实现高并发和整套缓存逻辑,以及实现go module proxy协议,即可重构服务。

作者整体代码较为整洁,可以作为项目借鉴,是一个很好的开源项目。其得到qiniu的支持,也是一个很好的服务;赞扬作者的贡献,期待继续完善。后续可以建议实现缓存淘汰和替换等功能,因为在底层存储有限时,还是需要进行重用

补充说明:

通过阅读代码文档发现,其还可以作为第三方服务实现链式代理;我们可以简单引入goproxy模块,即可以实现自己的服务,并且通过代码即可实现配置,无需配置文档;这也是一种很好的实现方式。样例代码如下,具体可以参考项目简介:

package main

import (
    "fmt"
    "net/http"
    "os"
    "strconv"

    "github.com/goproxy/goproxy"
)

func main() {
    g := goproxy.New()
    port := 8080
    g.GoBinEnv = append(
        os.Environ(),
        "GOPROXY=https://goproxy.cn,direct", // Use goproxy.cn as the upstream proxy
        "GOPRIVATE=git.example.com",         // Solve the problem of pulling private modules
    )
    g.ProxiedSUMDBs = []string{"sum.golang.org https://goproxy.cn/sumdb/sum.golang.org"} // Proxy the default checksum database
    fmt.Print("running on port ", port)
    http.ListenAndServe("127.0.0.1:"+strconv.Itoa(port), g)
}

最后,感谢大家的阅读;上述只是我的简要感悟,只代表我个人的想法,欢迎大家批评指正!

2020-12-20 补充:

关于goproxy还有一个视频,感兴趣的同学可以参考:第 61 期 2019-09-26 Go Modules、Go Module Proxy 和 goproxy.cn

一篇关于goproxy测试的文章,可以作为测试借鉴:Go 模块代理超大型库初始化速度实测:goproxy.cn vs goproxy.io