系列索引
為什么以及什么
項(xiàng)目,依賴項(xiàng)和Gopls
最小版本選擇
鏡像胀茵,校驗(yàn)和和Athens
Gopls改進(jìn)
vendor的使用
介紹
當(dāng)我第一次學(xué)習(xí)模塊時(shí),我遇到的一個(gè)長(zhǎng)期問(wèn)題是模塊鏡像挟阻,校驗(yàn)和以及Athens如何工作琼娘。Go團(tuán)隊(duì)已經(jīng)撰寫了大量有關(guān)模塊鏡像和校驗(yàn)和的文章,但是我希望在這里將最重要的信息整合在一起附鸽。在本文中脱拼,我提供了這些系統(tǒng)的用途,擁有的不同配置選項(xiàng)坷备,并使用示例程序展示了這些系統(tǒng)的實(shí)際作用熄浓。
模塊鏡像
模塊鏡像是在2019年八月推出,是Go1.13版本獲取模塊的默認(rèn)系統(tǒng)省撑。模塊鏡像作為VCS環(huán)境之前的代理服務(wù)器赌蔑,以幫助加快構(gòu)建本地應(yīng)用程序所需的模塊的下載。代理服務(wù)器實(shí)現(xiàn)了基于REST的API竟秫,并根據(jù)Go工具的需求進(jìn)行了設(shè)計(jì)娃惯。
模塊鏡像將緩存已請(qǐng)求的模塊及其特定版本,從而可以更快地檢索將來(lái)的請(qǐng)求肥败。一旦代碼被獲取并緩存在模塊鏡像中趾浅,那么它也可以將其快速提供給世界各地的用戶。模塊鏡像還允許用戶繼續(xù)從其原始VCS位置獲取不再可用的源代碼拙吉。這可以避免類似于一個(gè)Node開發(fā)者2016年的經(jīng)歷 潮孽。
校驗(yàn)和數(shù)據(jù)庫(kù)
校驗(yàn)和數(shù)據(jù)庫(kù)也于2019八月推出,是模塊起源的散列碼防篡改日志筷黔,可以用來(lái)驗(yàn)證不可信的代理往史。校驗(yàn)和數(shù)據(jù)庫(kù)以服務(wù)的方式實(shí)現(xiàn),可以被Go工具使用于模塊的驗(yàn)證佛舱。它可以驗(yàn)證任何給定的特定版本的模塊的代碼是否相同椎例,而不管它是誰(shuí)挨决,從哪里通過(guò)什么途徑獲取的。它還解決了其他依賴項(xiàng)管理系統(tǒng)尚未解決的其他安全問(wèn)題(如上面的鏈接中所述)订歪。Google擁有唯一的校驗(yàn)和數(shù)據(jù)庫(kù)脖祈,但是可以通過(guò)私有模塊鏡像對(duì)其進(jìn)行緩存,稍后會(huì)講述刷晋。
模塊索引
索引服務(wù)為那些想在google模塊鏡像列表后新增模塊的開發(fā)者提供服務(wù)盖高。比如pkg.go.dev之類的網(wǎng)站使用索引來(lái)檢索和發(fā)布有關(guān)模塊的信息。
你的隱私
如隱私權(quán)政策中所述眼虱,Go團(tuán)隊(duì)已構(gòu)建了這些服務(wù)喻奥,以保留盡可能少的使用信息,同時(shí)仍確保它們能夠檢測(cè)并修復(fù)問(wèn)題捏悬。但是撞蚕,可識(shí)別個(gè)人身份的信息(例如IP地址)最多保留30天。如果這對(duì)你或你的公司來(lái)說(shuō)是個(gè)問(wèn)題过牙,那么你可能不希望使用Go團(tuán)隊(duì)的服務(wù)來(lái)滿足模塊的獲取和驗(yàn)證需求甥厦。
Athens
Athens是一個(gè)模塊鏡像,你可以搭建在自己的私人環(huán)境中寇钉。使用私有模塊鏡像的一個(gè)原因是允許緩存公共模塊鏡像無(wú)法訪問(wèn)的私有模塊刀疙。出色的是Athens項(xiàng)目提供了一個(gè)在Docker Hub上發(fā)布的Docker容器,因此不需要特殊的安裝扫倡。
代碼1
docker run -p '3000:3000' gomods/athens:latest
代碼1顯示了如何使用Docker運(yùn)行本地Athens服務(wù)器庙洼。我們稍后將使用它來(lái)查看Go工具的運(yùn)行情況,并監(jiān)視所有Go工具Web調(diào)用的Athens日志镊辕。請(qǐng)注意油够,默認(rèn)情況下,Athens Docker鏡像使用臨時(shí)磁盤存儲(chǔ)啟動(dòng)征懈,因此當(dāng)你關(guān)閉正在運(yùn)行的容器時(shí)石咬,所有內(nèi)容都會(huì)消失。
Athens還具有代理校驗(yàn)和數(shù)據(jù)庫(kù)的能力卖哎。當(dāng)Go工具配置為使用像Athens這樣的私有模塊鏡像時(shí)鬼悠,當(dāng)Go工具需要從校驗(yàn)和數(shù)據(jù)庫(kù)中查找哈希碼的時(shí)候,它也會(huì)嘗試使用同一個(gè)私有模塊鏡像亏娜。如果你使用的私有模塊鏡像不支持代理校驗(yàn)和數(shù)據(jù)庫(kù)焕窝,那么除非專門關(guān)閉校驗(yàn)和數(shù)據(jù)庫(kù),否則將直接訪問(wèn)默認(rèn)的校驗(yàn)和數(shù)據(jù)庫(kù)维贺。
代碼2
http://localhost:3000/sumdb/sum.golang.org/latest
go.sum database tree
756113
k9nFMBuXq8uk+9SQNxs/Vadri2XDkaoo96u4uMa0qE0=
— sum.golang.org Az3grgIHxiDLRpsKUElIX5vJMlFS79SqfQDSgHQmON922lNdJ5zxF8SSPPcah3jhIkpG8LSKNaWXiy7IldOSDCt4Pwk=
代碼2顯示了Athens如何成為校驗(yàn)和數(shù)據(jù)庫(kù)代理它掂。第一行中列出的URL要求本地運(yùn)行的Athens服務(wù)從校驗(yàn)和數(shù)據(jù)庫(kù)中檢索有關(guān)最新簽名樹的信息。你可以看到為什么GOSUMDB配置了名稱而不是URL。
環(huán)境變量
有幾個(gè)環(huán)境變量可以控制Go工具的操作虐秋,因?yàn)樗c模塊鏡像和校驗(yàn)和數(shù)據(jù)庫(kù)有關(guān)榕茧。需要為每個(gè)開發(fā)人員或構(gòu)建環(huán)境設(shè)置這些變量。
GOPROXY:一組指向模塊鏡像的URL客给,用于獲取模塊用押。如果你希望Go工具直接從VCS位置獲取模塊,則可以將其設(shè)置為direct靶剑。如果將此設(shè)置為off蜻拨,則將不會(huì)下載模塊。off可以在vendor或模塊緩存被保護(hù)的環(huán)境中構(gòu)建項(xiàng)目時(shí)使用桩引。
GOSUMDB:校驗(yàn)和數(shù)據(jù)庫(kù)的名稱官觅,用于驗(yàn)證給定模塊/版本的代碼未隨時(shí)間變化。此名稱用于形成一個(gè)適當(dāng)?shù)腢RL阐污,該URL告訴Go工具去哪里檢索校驗(yàn)和數(shù)據(jù)庫(kù)。該URL可以指向Google擁有的校驗(yàn)和數(shù)據(jù)庫(kù)咱圆,也可以指向支持對(duì)校驗(yàn)和數(shù)據(jù)庫(kù)緩存或代理的本地模塊鏡像笛辟。如果你不需要Go工具驗(yàn)證并添加到go.sum文件中的給定模塊/版本的哈希碼,也可以將其設(shè)置為off序苏。只有將新的go.sum行添加到go.sum文件之前手幢,才檢索校驗(yàn)和數(shù)據(jù)庫(kù)。
GONOPROXY:一組基于URL的模塊路徑忱详,不使用模塊鏡像來(lái)獲取围来,而直接在VCS位置上獲取。
GONOSUMDB:一組基于URL的模塊路徑匈睁,這些模塊的哈希碼不在校驗(yàn)和數(shù)據(jù)庫(kù)中查找监透。
GOPRIVATE:一個(gè)方便的變量,用于將GONOPROXY和GONOSUMDB設(shè)置為相同的默認(rèn)值航唆。
隱私語(yǔ)義
在考慮隱私和項(xiàng)目所依賴的模塊時(shí)胀蛮,需要考慮幾件事。尤其是你不希望任何人知道的私有模塊糯钙。下表提供了隱私選項(xiàng)粪狼。再?gòu)?qiáng)調(diào)一次,需要為每個(gè)開發(fā)人員或構(gòu)建環(huán)境配置成計(jì)算機(jī)級(jí)別設(shè)置任岸。
代碼3
Option : Fetch New Modules : Validate New Checksums
-----------------------------------------------------------------------------------------
Complete Privacy : GOPROXY="direct" : GOSUMDB="off"
Internal Privacy : GOPROXY="Private_URL" : GOSUMDB="sum.golang.org"
GONOSUMDB="github.com/mycompany/*,gitlab.com/*"
No Privacy : GOPROXY="Public_URL" : GOSUMDB="sum.golang.org"
完全的私密性:直接從VCS服務(wù)器獲取代碼再榄,并且不會(huì)從校驗(yàn)和數(shù)據(jù)庫(kù)中查找哈希碼或添加到go.sum
文件。
內(nèi)部隱私:通過(guò)像Athens這樣的私有模塊鏡像獲取代碼享潜,針對(duì)GONOSUMDB
下面列出的指定URL路徑困鸥,并且不會(huì)在校驗(yàn)和數(shù)據(jù)庫(kù)中查找哈希碼并添加到go.sum
文件中。如有必要剑按,不在GONOSUMDB
中列出的模塊將會(huì)去校驗(yàn)和數(shù)據(jù)庫(kù)中檢索窝革。
沒(méi)有隱私:通過(guò)Google或JFrog的公共服務(wù)器等公共模塊鏡像獲取代碼购城。在這種情況下,你依賴的所有模塊都必須是公共模塊虐译,并且可以通過(guò)你選擇的公共模塊鏡像進(jìn)行訪問(wèn)瘪板。這些公共模塊鏡像將記錄你的請(qǐng)求以及其中包含的詳細(xì)信息。還將記錄對(duì)Google擁有的校驗(yàn)和數(shù)據(jù)庫(kù)的訪問(wèn)記錄漆诽。所有記錄的信息會(huì)遵守隱私政策侮攀。
從來(lái)不會(huì)出現(xiàn)要在校驗(yàn)和數(shù)據(jù)庫(kù)中查找私有模塊的哈希碼的情況,因?yàn)樵谛r?yàn)和數(shù)據(jù)庫(kù)中永遠(yuǎn)不會(huì)列出這些模塊厢拭。私有模塊不會(huì)允許公用模塊鏡像訪問(wèn)兰英,因此不會(huì)生成并存儲(chǔ)哈希碼。對(duì)于私有模塊供鸠,你需要依靠?jī)?nèi)部策略和實(shí)踐來(lái)保證模塊/版本的代碼保持一致畦贸。但是,如果私有模塊/版本的代碼確實(shí)發(fā)生了變化楞捂,那么當(dāng)首次在新機(jī)器上獲取并緩存模塊/版本時(shí)薄坏,Go工具仍會(huì)發(fā)現(xiàn)差異。
每當(dāng)將模塊/版本添加到計(jì)算機(jī)上的本地緩存中并且在go.sum文件中記錄寨闹,就將go.sum文件中的哈希碼與剛剛從緩存中獲取的哈希碼進(jìn)行比較胶坠。如果哈希碼不匹配,則說(shuō)明已更改繁堡。關(guān)于此工作流程的最佳部分是不需要依賴校驗(yàn)和數(shù)據(jù)庫(kù)查找沈善,這樣仍可以驗(yàn)證任何給定版本的私有模塊,而不會(huì)有隱私泄露的問(wèn)題椭蹄。顯然闻牡,這完全取決于你何時(shí)首次獲取私有模塊/版本,對(duì)于存儲(chǔ)在校驗(yàn)和數(shù)據(jù)庫(kù)中的公共模塊/版本來(lái)說(shuō)绳矩,這是同樣的問(wèn)題澈侠。
當(dāng)使用Athens搭建模塊鏡像服務(wù)時(shí),也要考慮Athens的配置選項(xiàng)埋酬。
代碼4
GlobalEndpoint = "https://<url_to_upstream>"
NoSumPatterns = ["github.com/mycompany/*]
代碼4中的這些設(shè)置來(lái)自Athens文檔哨啃,它們很重要。默認(rèn)情況下写妥,Athens將直接從不同的VCS服務(wù)器獲取模塊拳球。這樣可以保持你的私有環(huán)境的隱私級(jí)別為最高級(jí)別。但是珍特,你可以通過(guò)設(shè)置GlobalEnpoint的URL祝峻,將Athens指向其他模塊鏡像。這將使你在獲取新的公共模塊時(shí)有更好的性能,但是將失去隱私的保護(hù)莱找。
另一個(gè)設(shè)置NoSumPatterns酬姆,它用于幫助開發(fā)人員驗(yàn)證構(gòu)建環(huán)境是否已正確配置。開發(fā)人員需要將添加到GONOSUMDB的同一組路徑也添加到NoSumPatterns中奥溺。每當(dāng)校驗(yàn)和數(shù)據(jù)庫(kù)請(qǐng)求到Athens尋找與該路徑匹配的模塊時(shí)辞色,它將返回狀態(tài)碼,該狀態(tài)代碼會(huì)使Go工具失敗浮定。這表明開發(fā)人員的設(shè)置錯(cuò)誤右蕊。換句話說(shuō)钟些,如果發(fā)出請(qǐng)求的機(jī)器配置正確寄纵,則該請(qǐng)求永遠(yuǎn)不會(huì)首先到達(dá)Athens碗降。
Vendoring
我相信每個(gè)項(xiàng)目都應(yīng)提供依賴項(xiàng)管理,直到這樣做不合理或?qū)嶋H不需要為止方灾。諸如Docker和Kubernetes之類的項(xiàng)目無(wú)法供應(yīng)其依賴項(xiàng)建蹄,因?yàn)関endor的依賴項(xiàng)太多了。但是裕偿,對(duì)于我們大多數(shù)人而言洞慎,情況并非如此。在v1.14版本中击费,對(duì)vendor和模塊提供了強(qiáng)大的支持。我將在另一篇文章中討論桦他。
我提出Vendoring很重要的一點(diǎn)是蔫巩。我聽說(shuō)有人使用Athens或?qū)S媚K鏡像代替Vendoring。我認(rèn)為這是一個(gè)錯(cuò)誤快压,一個(gè)與另一個(gè)無(wú)關(guān)圆仔。你可能會(huì)爭(zhēng)辯說(shuō)模塊鏡像vendor的依賴性,因?yàn)槟K的代碼是持久的蔫劣,但是代碼與依賴它的項(xiàng)目仍然相去甚遠(yuǎn)坪郭。即使你相信模塊鏡像的可用性,我依然相信一個(gè)自身?yè)碛兴杷性创a的項(xiàng)目是無(wú)可替代的脉幢,這樣僅依靠項(xiàng)目本身來(lái)構(gòu)建代碼就可以了歪沃。
實(shí)用工具
有了所有這些背景知識(shí)之后,就該開始實(shí)踐Go工具了嫌松。為了了解環(huán)境變量如何影響Go工具沪曙,我將運(yùn)行一些不同的場(chǎng)景。在開始之前萎羔,可以通過(guò)運(yùn)行g(shù)o env命令找到默認(rèn)值液走。
代碼5
$ go env
GONOPROXY=""
GONOSUMDB=""
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOSUMDB="sum.golang.org"
代碼5顯示了默認(rèn)值,這些默認(rèn)值告訴Go工具使用Google模塊鏡像和Google校驗(yàn)和數(shù)據(jù)庫(kù)。如果這些Google服務(wù)可以訪問(wèn)你所需的所有代碼缘眶,則建議使用此配置嘱根。如果訪問(wèn)Google模塊鏡像恰好響應(yīng)410(消失)或404(未找到),則使用direct(這是GOPROXY配置的一部分)將允許Go工具更改獲取路徑并直接通過(guò)模塊/版本VCS的位置獲取巷懈。任何其他狀態(tài)碼(例如500)將導(dǎo)致Go工具失敗该抒。
如果Google模塊鏡像針對(duì)給定的模塊/版本恰好以410或404響應(yīng),那是因?yàn)樗辉谄渚彺嬷性矣鳎⑶铱赡艽四K不可緩存柔逼,就像私有模塊一樣。在這種情況下割岛,很有可能在校驗(yàn)和數(shù)據(jù)庫(kù)中也沒(méi)有列出愉适。即使Go工具可以成功獲取模塊/版本,但針對(duì)校驗(yàn)和數(shù)據(jù)庫(kù)的檢索將失敗癣漆,并且Go工具最終仍將失敗维咸。這些是使用私有模塊時(shí)需要注意的事項(xiàng)。
由于無(wú)法顯示任何Google模塊鏡像的日志惠爽,因此我將使用Athens運(yùn)行本地模塊鏡像癌蓖。這可以讓你看到實(shí)際使用的Go工具和模塊鏡像的效果。Athens實(shí)現(xiàn)了相同的語(yǔ)義和工作流程婚肆。
項(xiàng)目
要?jiǎng)?chuàng)建項(xiàng)目租副,啟動(dòng)終端會(huì)話并創(chuàng)建項(xiàng)目結(jié)構(gòu)。
代碼6
$ cd $HOME
$ mkdir app
$ mkdir app/cmd
$ mkdir app/cmd/db
$ touch app/cmd/db/main.go
$ cd app
$ go mod init app
$ code .
代碼6顯示了運(yùn)行命令后在磁盤上創(chuàng)建的項(xiàng)目結(jié)構(gòu)较性,初始化項(xiàng)目的模塊以及使VS Code運(yùn)行用僧。
代碼7
https://play.golang.org/p/h23opcp5qd0
01 package main
02
03 import (
04 "context"
05 "log"
06
07 "github.com/Bhinneka/golib"
08 db "gopkg.in/rethinkdb/rethinkdb-go.v5"
09 )
10
11 func main() {
12 c, err := db.NewCluster([]db.Host{{Name: "localhost", Port: 3000}}, nil)
13 if err != nil {
14 log.Fatalln(err)
15 }
16
17 if _, err = c.Query(context.Background(), db.Query{}); err != nil {
18 log.Fatalln(err)
19 }
20
21 golib.CreateDBConnection("")
22 }
代碼7顯示main.go
中的代碼。設(shè)置好項(xiàng)目并完成主要功能后赞咙,我將在項(xiàng)目上運(yùn)行三種不同的方案责循,以便于更好地理解環(huán)境變量和Go工具的使用。
方案1-Athens模塊鏡像
在這種情況下攀操,我使用Athens將Google模塊鏡像替換為私有模塊鏡像院仿。
代碼8
GONOSUMDB=""
GONOPROXY=""
GOSUMDB="sum.golang.org"
GOPROXY="http://localhost:3000,direct"
代碼8顯示了我要求Go工具指向在本地端口3000運(yùn)行的Athens模塊鏡像服務(wù)。如果模塊鏡像以410(消失)或404(未找到)響應(yīng)速和,則嘗試直接拉取模塊歹垫。默認(rèn)情況下,如有必要颠放,Go工具現(xiàn)在將使用Athens訪問(wèn)校驗(yàn)和數(shù)據(jù)庫(kù)县钥。
接下來(lái),啟動(dòng)一個(gè)新的終端會(huì)話慈迈,運(yùn)行Athens若贮。
代碼9
$ docker run -p '3000:3000' -e ATHENS_LOG_LEVEL=debug -e GO_ENV=development gomods/athens:latest
time="2020-01-21T21:12:35Z" level=info msg="Exporter not specified. Traces won't be exported"
2020-01-21 21:12:35.937604 I | Starting application at port :3000
代碼9在第一行顯示了在新的終端會(huì)話中運(yùn)行的命令省有,啟動(dòng)Athens服務(wù)并通過(guò)額外的參數(shù)調(diào)試日志運(yùn)行。首先仔細(xì)檢查你的Docker是否在本地運(yùn)行谴麦。Athens開始之后蠢沿,你應(yīng)該可以看到上述的輸出。
要查看Go工具如何使用Athens服務(wù)匾效,請(qǐng)?jiān)趧?chuàng)建項(xiàng)目的原始終端會(huì)話中運(yùn)行以下命令舷蟀。
代碼10
$ export GOPROXY="http://localhost:3000,direct"
$ rm go.*
$ go mod init app
$ go mod tidy
代碼10顯示了將GOPROXY變量設(shè)置為使用Athens服務(wù),刪除原本的模塊文件并重新初始化應(yīng)用程序的命令面哼。最終命令go mod tidy將使Go工具通過(guò)Athens服務(wù)獲取構(gòu)建此項(xiàng)目所需的模塊野宜。
代碼11
handler: GET /github.com/!bhinneka/@v/list [404]
handler: GET /github.com/@v/list [404]
handler: GET /github.com/!bhinneka/golib/@v/list [200]
handler: GET /gopkg.in/@v/list [404]
handler: GET /github.com/!bhinneka/golib/@latest [200]
handler: GET /gopkg.in/rethinkdb/rethinkdb-go.v5/@v/list [200]
handler: GET /github.com/bitly/@v/list [404]
handler: GET /github.com/bmizerany/@v/list [404]
handler: GET /github.com/bmizerany/assert/@v/list [200]
handler: GET /github.com/bitly/go-hostpool/@v/list [200]
handler: GET /github.com/bmizerany/assert/@latest [200]
代碼11顯示了Athens服務(wù)的更重要的輸出。如果查看go.mod和go.sum文件魔策,將看到列出了用于構(gòu)建和驗(yàn)證項(xiàng)目的所有內(nèi)容匈子。
場(chǎng)景2-Athens 模塊鏡像 / GitHub 模塊直接獲取
在這種場(chǎng)景下,我不希望通過(guò)模塊鏡像獲取托管在GitHub上的模塊闯袒。我希望直接從GitHub中獲取這些模塊虎敦。
代碼12
$ export GONOPROXY="github.com"
$ export GOPROXY="http://localhost:3000,direct"
$ rm go.*
$ go mod init app
$ go mod tidy
代碼12顯示了在這種情況下如何設(shè)置GONOPROXY
變量。GONOPROXY
將會(huì)告訴Go工具政敢,所有名稱以github.com
開始的模塊其徙,使用直接獲取的方式。不要使用GOPROXY
變量定義的模塊鏡像喷户。雖然我使用GitHub為例唾那,如果你運(yùn)行一個(gè)本地VCS像GitLab,這種配置也可以完美符合你的需求褪尝。這將允許你直接獲取私有模塊闹获。
代碼13
handler: GET /gopkg.in/@v/list [404]
handler: GET /gopkg.in/rethinkdb/rethinkdb-go.v5/@v/list [200]
代碼13顯示了運(yùn)行g(shù)o mod tidy后Athens服務(wù)的更重要的輸出。這次恼五,Athens只顯示了對(duì)位于gopkg.in的兩個(gè)模塊的請(qǐng)求昌罩。Athens服務(wù)不再請(qǐng)求位于github.com的模塊哭懈。
方案3-模塊鏡像404
在這種情況下灾馒,我將使用自己的模塊鏡像,該模塊鏡像將為每個(gè)模塊請(qǐng)求返回404遣总。當(dāng)模塊鏡像返回410(消失)或404(未找到)時(shí)睬罗,Go工具將繼續(xù)以逗號(hào)分隔的GOPROXY
變量列表中列出的其他鏡像集。
代碼14
https://play.golang.org/p/uEH4_b6QrAO
01 package main
02
03 import (
04 "log"
05 "net/http"
06 )
07
08 func main() {
09 h := func(w http.ResponseWriter, r *http.Request) {
10 log.Printf("%s %s -> %s\n", r.Method, r.URL.Path, r.RemoteAddr)
11 w.WriteHeader(http.StatusNotFound)
12 }
13 http.ListenAndServe(":3000", http.HandlerFunc(h))
14 }
代碼14顯示了我的模塊鏡像中的代碼旭斥。它能夠記錄每個(gè)請(qǐng)求并返回http.StatusNotFound
容达,即404狀態(tài)碼。
代碼15
$ unset GONOPROXY
$ export GOPROXY="http://localhost:3000"
$ rm go.*
$ go mod init app
$ go mod tidy
代碼15顯示了如何將GONOPROXY
變量重新設(shè)置為空垂券,以及如何在再次運(yùn)行go mod tidy
之前將其direct
從GOPROXY
中刪除花盐。
代碼16
app/cmd/db imports
github.com/Bhinneka/golib: cannot find module providing package github.com/Bhinneka/golib
app/cmd/db imports
gopkg.in/rethinkdb/rethinkdb-go.v5: cannot find module providing package gopkg.in/rethinkdb/rethinkdb-go.v5
代碼16顯示了運(yùn)行go mod tidy
時(shí)Go工具的輸出羡滑。你會(huì)看到調(diào)用失敗,因?yàn)镚o工具找不到模塊算芯。
如果我把direct
放回到GOPROXY
變量中呢柒昏?
代碼17
$ unset GONOPROXY
$ export GOPROXY="http://localhost:3000,direct"
$ rm go.*
$ go mod init app
$ go mod tidy
代碼17顯示了如何再次將direct
加入GOPROXY
變量。
代碼18
go: finding github.com/Bhinneka/golib latest
go: finding gopkg.in/rethinkdb/rethinkdb-go.v5 v5.0.1
go: downloading gopkg.in/rethinkdb/rethinkdb-go.v5 v5.0.1
go: extracting gopkg.in/rethinkdb/rethinkdb-go.v5 v5.0.1
代碼18顯示了Go工具再次工作熙揍,并直接進(jìn)入每個(gè)VCS系統(tǒng)以獲取模塊职祷。請(qǐng)記住,如果返回任何其他狀態(tài)碼(200届囚、410或404之外)有梆,則Go工具將執(zhí)行失敗。
其他情況
我不再演示繼續(xù)其他只會(huì)導(dǎo)致Go工具失敗的場(chǎng)景意系。如果使用私有模塊泥耀,則需要一個(gè)私有模塊鏡像,并且每個(gè)開發(fā)人員和構(gòu)建機(jī)器上的配置都很重要昔字,需要保持一致爆袍。私有模塊鏡像的配置需要與開發(fā)人員和構(gòu)建計(jì)算機(jī)上的配置匹配。然后作郭,使用GONOPROXY和GONOSUMDB環(huán)境變量來(lái)防止對(duì)私有模塊的請(qǐng)求發(fā)送到任何Google服務(wù)器陨囊。如果你使用的是Athens,它具有特定的配置選項(xiàng)夹攒,可在幫助開發(fā)人員或構(gòu)建機(jī)器上查找配置差異蜘醋。
VCS身份驗(yàn)證問(wèn)題
在這篇文章的審閱過(guò)程中,Erdem Aslan非常友好咏尝,并為人們遇到的問(wèn)題提供解決方案压语。獲取依賴時(shí)的Go工具期望使用基于https
的協(xié)議。在需要對(duì)VCS進(jìn)行身份驗(yàn)證的環(huán)境中编检,這可能是個(gè)問(wèn)題胎食。Athens可以解決這個(gè)問(wèn)題,但是如果你要確保直接調(diào)用不會(huì)失敗允懂,Erdem為全局git配置文件提供了這些設(shè)置厕怜。
代碼19
[url "git@github.com:"]
insteadOf = "https://github.com"
pushInsteadOf = "github:"
pushInsteadOf = "git://github.com/"
結(jié)論
當(dāng)你開始在自己的項(xiàng)目中使用模塊時(shí),請(qǐng)確保提前決定要使用的模塊鏡像蕾总。如果你使用私有VCS或隱私安全是一個(gè)大問(wèn)題粥航,那么使用私有模塊鏡像是你的最佳選擇。這將提供你所需的所有安全性生百,用于獲取模塊的更好性能以及最高級(jí)別的隱私保護(hù)递雀。Athens是運(yùn)行私有模塊鏡像的理想選擇,因?yàn)樗峁┝四K緩存和校驗(yàn)和數(shù)據(jù)庫(kù)代理蚀浆。
如果要檢查Go工具是否遵循你的配置缀程,并且所選的模塊鏡像是否正確代理了校驗(yàn)和數(shù)據(jù)庫(kù)搜吧,Go工具提供一個(gè)名為go mod verify
的命令。此命令可以檢查下載的依賴項(xiàng)是否未被修改杨凑。它將檢查本地模塊緩存中的內(nèi)容或即將在1.15版中發(fā)布的內(nèi)容赎败,該命令可以檢查vendor文件夾。
試用這些配置項(xiàng)蠢甲,找到能滿足你需求的最佳解決方案僵刮。