昨天 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
。