昨天 Go 1.13 終於釋出了,雖然比預期延遲了半個月之久,但畢竟遲到總比不到好。
Go 1.13 的釋出為 Go 帶來了不少變化(詳見:https://golang.org/doc/go1.13 ),有些變化可能是開發者無法直接感覺到的,但有些又是和開發者日常開發息息相關的。其中,Go modules 的扶正就是這次 Go 1.13 釋出中開發者能直接感覺到的最大變化。
Go modules 最早釋出於 Go 1.11,經過兩個版本的更新後,它作為依賴管理解決方案來說現在已經變得光彩奪目。隨著 Go modules 一起被髮布的還有一個叫做 Module proxy protocol
的協議,通過它我們可以搭建 Go 模組代理,最後交由 GOPROXY
環境變數以指引 go 命令後續在抓取模組時的途徑。
對於我們們中國的開發者來說,一個優秀的 Go 模組代理可以幫助我們解決很多問題。比如 Go 語言中最知名的 golang.org/x/...
模組在中國大陸是無法訪問到的,以前我們會用很多其他的辦法來抓取他們,而若依靠一個可以訪問到它們的模組代理,那麼將事半功倍。
更因為 Go 1.13 將 GOPROXY
預設成了中國大陸無法訪問的 https://proxy.golang.org ,所以我們中國的開發者從今以後必須先修改 GOPROXY
才能正常使用 go 來開發應用了。為此,我們聯合中國備受信賴的雲服務提供商七牛雲專門為我們們中國開發者而打造了一個 Go 模組代理:goproxy.cn
。
什麼是 goproxy.cn?
goproxy.cn
是目前中國最可靠的 Go 模組代理,這個如果有人存在質疑可以一一測試比對列表中所有能在國內訪問的代理。對於那個和 goproxy.cn
域名比較相近的 goproxy.io
,我之前已經發表過一篇實測文章(詳見:https://studygolang.com/topic... )。
goproxy.cn
還是是一個非營利性專案,目標是為中國和世界上其他地方的 Gopher 們提供一個免費的、可靠的、持續線上的且經過 CDN 加速的模組代理。正因為 goproxy.cn
由中國 Go 語言第一個吃螃蟹的大公司七牛雲執行,所以它的穩定性和執行速度都是毋庸置疑的,如果你的網路環境本身不差的情況下,它能快到讓你不可思議,比 go get
傳統的抓取方式快上了不止幾倍。
有人可能會問阿里雲的也很快,而且阿里雲也是大廠,為什麼不用阿里雲的模組代理(mirrors.aliyun.com/goproxy)。我只能說,當我在使用阿里雲的代理做初始化 github.com/kubernetes/kubernetes
的測試時,出現了大量的 404 錯誤以至於初始化操作無法完成……而且它還不支援代理 GOSUMDB
的預設值也就是 sum.golang.org
,因此你還得手動修改 GOSUMDB
才能夠正常使用 go
。在速度旗鼓相當的情況下,為什麼不考慮直接使用一個更穩定、高可用的呢?而且畢竟 goproxy.cn
這個域名也很好記不是嘛~你只用記住 goproxy
和 .cn
,就沒了。
Q&A
問:在 Go 1.13 中如何使用 goproxy.cn?
答:一條 go env -w GOPROXY=https://goproxy.cn,direct
即可。之所以在後面拼接一個 ,direct
,是因為通過這樣做我們可以在一定程度上解決私有庫的問題(當然, goproxy.cn 無法訪問你的私有庫)。這個 GOPROXY
設定的工作原理是:當 go
在抓取目標模組時,若遇見了 404 錯誤,那麼就回退到 direct
也就是直接去目標模組的源頭(比如 GitHub) 去抓取。而恰好,GitHub 等類似的程式碼託管網站的原則基本都是“你無權訪問的你來說就是不存在的”,所以我才說通過這樣設定可以在一定程度上解決私有庫無法通過模組代理訪問的問題。
問:在 Go 1.13 之前如何使用 goproxy.cn?
答:同樣也是設定環境變數即可,但是得你手動配置,而且還不能使用上述的那個 ,direct
字尾,因為那是 Go 1.13 剛加的特性。詳細配置方法可以參見 goproxy.cn 的 README 檔案。
問:在 Go 1.13 中如何解決私有庫問題?
答:在上述的回答中我有提到可以通過 Go 1.13 為 GOPROXY
新增的“代理列表”特性來為 goproxy.cn 做一個 fallback 選項,也就是 direct
(直接從目標模組源頭抓取),它就是解決私有庫的一種途徑,但並不是一個完美的解決方案。為此,Go 1.13 還推出了一個 GONOPROXY
環境變數(詳見: https://golang.org/cmd/go/#hdr-Environment_variables ),通過設定它我們可以實現控制讓哪些 module path 忽略 GOPROXY
,無腦回源。比如 GONOPROXY=*.corp.example.com
就意味著 go
在抓取所有 corp.example.com
的三級子域名下的所有模組時都將忽略 GOPROXY
設定直接回源到目標模組的原地址。
問:在 Go 1.13 中如何防止從公共模組代理中抓取的模組被篡改?
答:Go 1.13 新推出了一個 GOSUMDB
(預設值是 sum.golang.org ,國內無法訪問),就是為了實現這個目的,它的值是一個可信任的模組校驗和資料庫地址,通過指定它,go
將在抓取完模組時(無論是否是經過模組代理抓取的)對所有模組進行雜湊校驗,只有和校驗和資料庫中現有的一致時才算抓取成功。同 GONOPROXY
一樣,Go 1.13 也為 GOSUMDB
配對釋出了一個 GONOSUMDB
,用法一致,作用是控制 go
應該忽略校驗哪些 module path 下的模組。
問:分別設定 GONOPROXY
和 GONOSUMDB
很麻煩,有沒有更好的辦法?
答:有,Go 1.13 為了方便管理私有庫規則,還推出了一個 GOPRIVATE
,可以簡單地理解成通過設定它就同時設定了 GONOPROXY
和 GONOSUMDB
。
原文作者:@盛傲飛,已取得授權。