如何獲取 Go 服務依賴包
在服務治理中,我們有時需要統計業務方服務的依賴包版本號使用情況,以便進行升級和版本兼容,通過 Go 官方提供的 debug.ReadBuildInfo
可以很方便的實現。
debug.ReadBuildInfo
ReadBuildInfo 是 Go 標準庫提供的方法,通過該方法可以讀取打包程序的構建信息,裏面就包括我們想要的依賴包和版本號信息。
// ReadBuildInfo returns the build information embedded in the running binary.
// The information is available only in binaries built with module support.
func ReadBuildInfo() (info *BuildInfo, ok bool)
可以看到該方法返回了兩個返回值:
*BuildInfo
表示構建信息ok
表示是否成功拿到構建信息
需要注意的是,只有在啓動 go module
時才能正常獲取到 BuildInfo
。
下面我們看下 debug.BuildInfo
結構體。
debug.BuildInfo
根據 Go 官方文檔 說明,BuildInfo 表示從運行的二進制文件讀取的構建信息。
type BuildInfo struct {
Path string // main 包路徑,比如:command-line-arguments
Main Module // main 包信息
Deps []*Module // 依賴包列表信息
}
繼續看下 Module
結構體:
type Module struct {
Path string // 包路徑
Version string // 包版本號
Sum string // 包校驗值
Replace *Module // 表示是否進行了 replace 替換
}
Module 表示一個模塊信息,main 包也是個 Module。
下面我們寫個代碼示例看下 BuildInfo 具體長什麼樣。
首先,寫一個 go.mod:
module gomod01
go 1.16
require (
github.com/davecgh/go-spew v1.1.1
)
然後,編寫 main.go
package main
import (
"runtime/debug"
"github.com/davecgh/go-spew/spew"
)
func main() {
res, ok := debug.ReadBuildInfo()
if ok {
spew.Dump(res)
}
}
運行:
(*debug.BuildInfo)(0xc0000522a0)({
Path: (string) (len=22) "command-line-arguments",
Main: (debug.Module) {
Path: (string) (len=7) "gomod01",
Version: (string) (len=7) "(devel)",
Sum: (string) "",
Replace: (*debug.Module)(<nil>)
},
Deps: ([]*debug.Module) (len=1 cap=1) {
(*debug.Module)(0xc00006a040)({
Path: (string) (len=26) "github.com/davecgh/go-spew",
Version: (string) (len=6) "v1.1.1",
Sum: (string) (len=47) "h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=",
Replace: (*debug.Module)(<nil>)
})
}
})
可以看到,當前 Go 程序的模塊名是 gomod01,以及依賴的第三方包和版本號都能拿到。
小結
- 官方提供的
debug.ReadBuildInfo
可以很方便的讀取依賴包 - Go 服務必須啓用 go module(go1.16 默認開啓)
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://maratrix.cn/post/2021/04/28/go-deps/