Go語言版本管理module以及go.sum詳解
為了確保一致性構(gòu)建,Go語言中引入了go.mod文件來標(biāo)記每個依賴包的版本,在構(gòu)建過程中g(shù)o命令會下載go.mod中的依賴包,下載的依賴包會緩存在本地,以便下次構(gòu)建。
在進(jìn)行g(shù)o語言項目開發(fā)的時候,會依賴3種類型的庫包:
- 內(nèi)置的標(biāo)準(zhǔn)庫包,在goroot/src目錄下,也就是我們安裝目錄的src目錄下(類似于python的bin目錄)
- 第三方庫包(git上開源的)
- 項目中的庫包,也就是項目中的其他目錄。自己調(diào)用自己寫的函數(shù)方法
生成go.mod文件
確保go版本>=1.11
在項目的根目錄下,執(zhí)行go mod init xxxx
xxxx為對應(yīng)的項目名稱。
例如:我們創(chuàng)建一個geecache的項目,在命令行執(zhí)行go mod init geecache
此時,項目目錄就產(chǎn)生了go.mod
go.sum
為了解決Go module的這一安全隱患,Go開發(fā)團隊在引入go.mod的同時也引入了go.sum文件,用于記錄每個依賴包的哈希值,在構(gòu)建時,如果本地的依賴包hash值與go.sum文件中記錄得不一致,則會拒絕構(gòu)建。
- 執(zhí)行
go mod tidy
命令,會生成go.sum
文件
go.sum文件詳解
go.sum文件中每行記錄由module 名, 版本和哈希組成,并由空格分開,格式如下:
<module> <version>[/go.mod] <hash>
例如:上述go.sum
中就記錄了github.com/golang/protobuf這個依賴v1.3.3版本的哈希值:
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
通常,每個依賴包版本會包含兩條記錄:
- 第一條為該依賴包版本整體(所有文件)的哈希值,
- 第二條僅表示該依賴包版本中
go.mod
文件的哈希值
如果該依賴包版本沒有go.mod
文件,則只有第一條記錄。如上面的例子中,v1.3.3 表示該依賴包版本整體,而v1.3.3/go.mod表示該依賴包版本中g(shù)o.mod文件。
依賴包版本中任何一個文件(包括go.mod
)改動,都會改變其整體哈希值,此處再 **額外記錄依賴包版本 **的go.mod
文件主要用于計算依賴樹時不必下載完整的依賴包版本,只根據(jù)go.mod
即可計算依賴樹。go.mod
只需要記錄直接依賴的依賴包版本,只在依賴包版本不包含go.mod
文件時候才會記錄間接依賴包版本。而go.sum
則是要記錄構(gòu)建用到的所有依賴包版本。
校驗
假設(shè)我們拿到某項目的源代碼并嘗試在本地構(gòu)建,go命令會從本地緩存中查找所有go.mod
中記錄的依賴包,并計算本地依賴包的哈希值,然后與go.sum
中的記錄進(jìn)行對比,即檢測本地緩存中使用的依賴包版本是否滿足項目go.sum
文件的期望。
如果校驗失敗,說明本地緩存目錄中依賴包版本的哈希值和項目中go.sum
中記錄的哈希值不一致,go命令將拒絕構(gòu)建。 這就是go.sum
存在的意義,即如果不使用我期望的版本,就不能構(gòu)建。
當(dāng)校驗失敗時,有必要確認(rèn)到底是本地緩存錯了,還是go.sum
記錄錯了。 需要說明的是,二者都可能出錯,本地緩存目錄中的依賴包版本有可能被有意或無意地修改過,項目中go.sum
中記錄的哈希值也可能被篡改過。
當(dāng)校驗失敗時,go命令傾向于相信go.sum
,因為一個新的依賴包版本在被添加到go.sum
前是經(jīng)過GOSUMDB(校驗和數(shù)據(jù)庫)驗證過的。此時即便系統(tǒng)中配置了GOSUMDB(校驗和數(shù)據(jù)庫),go命令也不會查詢該數(shù)據(jù)庫。
校驗和數(shù)據(jù)庫
環(huán)境變量GOSUMDB
標(biāo)識一個checksum database
,即校驗和數(shù)據(jù)庫,實際上是一個web服務(wù)器,該服務(wù)器提供查詢依賴包版本哈希值的服務(wù)。
該數(shù)據(jù)庫中記錄了很多依賴包版本的哈希值,比如Google官方的sum.golang.org則記錄了所有的可公開獲得的依賴包版本。除了使用官方的數(shù)據(jù)庫,還可以指定自行搭建的數(shù)據(jù)庫,甚至干脆禁用它(export GOSUMDB=off)。
如果系統(tǒng)配置了GOSUMDB
,在依賴包版本被寫入go.sum
之前會向該數(shù)據(jù)庫查詢該依賴包版本的哈希值進(jìn)行二次校驗,校驗無誤后再寫入go.sum
。
如果系統(tǒng)禁用了GOSUMDB
,在依賴包版本被寫入go.sum
之前則不會進(jìn)行二次校驗,go命令會相信所有下載到的依賴包,并把其哈希值記錄到go.sum中。
到此這篇關(guān)于Go語言版本管理go module以及go.sum詳解的文章就介紹到這了,更多相關(guān)Go語言 go module go.sum內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go使用TimerController解決timer過多的問題
多路復(fù)用,實際上Go底層也是一種多路復(fù)用的思想去實現(xiàn)的timer,但是它是底層的timer,我們需要解決的問題就過多的timer問題!本文給大家介紹了Go使用TimerController解決timer過多的問題,需要的朋友可以參考下2024-12-12Golang官方限流器time/rate的使用與實現(xiàn)詳解
限流器是后臺服務(wù)中十分重要的組件,在實際的業(yè)務(wù)場景中使用居多。time/rate?包基于令牌桶算法實現(xiàn)限流,本文主要為大家介紹了time/rate的使用與實現(xiàn),需要的可以參考一下2023-04-04golang 40行代碼實現(xiàn)通用協(xié)程池
golang協(xié)程機制很方便的解決了并發(fā)編程的問題,但是協(xié)程并不是沒有開銷的,所以也需要適當(dāng)限制一下數(shù)量。這篇文章主要介紹了golang 40行代碼實現(xiàn)通用協(xié)程池,需要的朋友可以參考下2018-08-08