Golang具有一套可以構(gòu)建和處理go源代碼的程序同辣,作為命令行工具聊倔,這些程序也并非直接運(yùn)行睡毒,而是由go程序調(diào)用。運(yùn)行這些程序最常見的方式是作為go程序的子命令逗物,例如 go fmt搬卒,該命令的運(yùn)行方式是由go程序使用適合于包級(jí)處理的參數(shù)調(diào)用底層二進(jìn)制文件,對(duì)go源代碼的完整包進(jìn)行操作翎卓;這些程序也可以作為獨(dú)立的二進(jìn)制文件運(yùn)行契邀,使用go tool子命令(如go tool cgo)使用未修改的參數(shù);某些命令(如pprof)只能通過(guò)go tool子命令訪問(wèn)失暴。go命令行作為日常開發(fā)的工具坯门,能大大方便編譯、調(diào)試逗扒、診斷程序性能等工作古戴,本文是對(duì)常見go命令行工具使用的匯總
go命令
go命令管理go源代碼并運(yùn)行此處列出的其他命令。在終端輸入go矩肩,會(huì)打印出如下信息
$ go
Go is a tool for managing Go source code.
Usage:
go <command> [arguments]
The commands are:
bug start a bug report
build compile packages and dependencies
clean remove object files and cached files
doc show documentation for package or symbol
env print Go environment information
fix update packages to use new APIs
fmt gofmt (reformat) package sources
generate generate Go files by processing source
get add dependencies to current module and install them
install compile and install packages and dependencies
list list packages or modules
mod module maintenance
run compile and run Go program
test test packages
tool run specified go tool
version print Go version
vet report likely mistakes in packages
Use "go help <command>" for more information about a command.
Additional help topics:
buildmode build modes
c calling between Go and C
cache build and test caching
environment environment variables
filetype file types
go.mod the go.mod file
gopath GOPATH environment variable
gopath-get legacy GOPATH go get
goproxy module proxy protocol
importpath import path syntax
modules modules, module versions, and more
module-get module-aware go get
module-auth module authentication using go.sum
module-private module configuration for non-public modules
packages package lists and patterns
testflag testing flags
testfunc testing functions
Use "go help <topic>" for more information about that to![]()pic.
下面介紹命令部分
啟動(dòng)錯(cuò)誤報(bào)告 運(yùn)行go bug
命令现恼,Bug打開默認(rèn)瀏覽器并啟動(dòng)新的Bug報(bào)告,報(bào)告包括有用的系統(tǒng)信息
編譯包和依賴項(xiàng) 用法如下
go build [-o output] [-i] [build flags] [packages]
build編譯由導(dǎo)入路徑命名的包及其依賴項(xiàng)黍檩,但不安裝編譯結(jié)果叉袍。如果build的參數(shù)是來(lái)自單個(gè)目錄的.go文件列表,則build會(huì)將它們視為指定單個(gè)包的源文件列表刽酱;編譯包時(shí)喳逛,build將忽略以"_test.go"結(jié)尾的文件
在編譯單個(gè)main包時(shí),build將生成的可執(zhí)行文件寫入以第一個(gè)源文件(go build ed.go rx.go
輸出的二進(jìn)制文件名為 'ed' 或 'ed.exe')或源代碼目錄(go build unix/sam
輸出的二進(jìn)制文件名為 'sam' 或 'sam.exe')命名的輸出文件(寫入Windows可執(zhí)行文件時(shí)會(huì)添加.exe
后綴)棵里;編譯多個(gè)包或單個(gè)非main包時(shí)润文,build會(huì)編譯包姐呐,但會(huì)丟棄生成的對(duì)象,僅用于檢查包是否可編譯
刪除對(duì)象文件和緩存文件 用法如下
go clean [clean flags] [build flags] [packages]
clean從包源目錄中刪除對(duì)象文件典蝌。go命令在一個(gè)臨時(shí)目錄中構(gòu)建大多數(shù)對(duì)象曙砂,因此go clean主要關(guān)注其他go工具或通過(guò)手動(dòng)調(diào)用go build
留下的對(duì)象文件
展示包或符號(hào)的文檔 用法
go doc [-u] [-c] [package|[package.]symbol[.methodOrField]]
go doc <pkg>
go doc <sym>[.<methodOrField>]
go doc [<pkg>.]<sym>[.<methodOrField>]
go doc [<pkg>.][<sym>.]<methodOrField>
// 在所有形式中,當(dāng)匹配符號(hào)時(shí)骏掀,參數(shù)中的小寫字母與任意一個(gè)大寫字母都匹配麦轰,
// 但大寫字母完全匹配。這意味著砖织,如果不同的符號(hào)有不同的大小寫,則包中的小寫參數(shù)可能有多個(gè)匹配項(xiàng)末荐。如果出現(xiàn)這種情況侧纯,則打印所有匹配的文檔
## 例子
go doc 展示當(dāng)前包的文檔
go doc Foo 展示當(dāng)前包中Foo的文檔(Foo為首字母大寫,因此不會(huì)匹配包路徑)
go doc encoding/json 展示encoding/json包文檔
go doc json encoding/json縮寫形式
go doc json.Number (或 go doc json.number) 展示json.Number的文檔和方法摘要
go doc json.Number.Int64 (或 go doc json.number.int64) 展示json.Number中Int64方法的文檔
go doc cmd/doc 顯示doc命名的包文檔
go doc -cmd cmd/doc 在doc命令中顯示包文檔和導(dǎo)出的符號(hào)
go doc template.new 展示html/template中New函數(shù)的文檔
go doc text/template.new 一個(gè)參數(shù)甲脏,展示text/template中New函數(shù)的文檔
go doc text/template new 兩個(gè)參數(shù)眶熬,展示text/template中New函數(shù)的文檔
打印go環(huán)境信息 用法
go env [-json] [-u] [-w] [var ...]
默認(rèn)情況下,env將信息打印為shell腳本(在windows上块请,是批處理文件)娜氏。如果一個(gè)或多個(gè)變量名作為參數(shù)給定,env將在其自己的行上打印每個(gè)命名變量的值
更新包以使用新的APIs 使用方法
go fix [packages]
fix對(duì)由導(dǎo)入路徑命名的包運(yùn)行g(shù)o fix命令墩新。fix查找使用舊api的go程序贸弥,并重寫它們以使用新的api; 更新到新的go版本后,fix將幫助您對(duì)程序進(jìn)行必要的更改海渊。使用
go tool fix [-r name,...] [path ...]
如果沒有顯式路徑绵疲,fix將讀取標(biāo)準(zhǔn)輸入并將結(jié)果寫入標(biāo)準(zhǔn)輸出; 如果命名路徑是一個(gè)文件,fix會(huì)就地重寫命名文件; 如果命名路徑是一個(gè)目錄臣疑,fix重寫該目錄中的所有.go文件樹
gofmt(重新格式化)源碼包 使用方法
go fmt [-n] [-x] [packages]
fmt在由導(dǎo)入路徑命名的包上運(yùn)行命令go fmt -l -w
盔憨,它打印被修改文件的名稱
-n標(biāo)志打印將要執(zhí)行的命令; -x標(biāo)志在執(zhí)行命令時(shí)打印命令
要了解更多關(guān)于gofmt細(xì)節(jié)可以運(yùn)行命令go doc cmd/gofmt
通過(guò)處理源碼生成go文件 使用方法
go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]
生成(必須顯示運(yùn)行)由現(xiàn)有文件中的指令描述的運(yùn)行命令。這些命令可以運(yùn)行任何進(jìn)程讯沈,但其意圖是創(chuàng)建或更新go源文件郁岩。它還接受標(biāo)準(zhǔn)的構(gòu)建標(biāo)志,包括-v缺狠,-n和-x: -v標(biāo)志在處理過(guò)程中打印包和文件的名稱; -n標(biāo)志打印將要執(zhí)行的命令; -x標(biāo)志在執(zhí)行命令時(shí)打印命令
將依賴項(xiàng)添加到當(dāng)前模塊并安裝它們 使用方法
go get [-d] [-t] [-u] [-v] [-insecure] [build flags] [packages]
get解析并向當(dāng)前開發(fā)模塊添加依賴項(xiàng)问慎,然后構(gòu)建并安裝它們
第一步,要解決添加哪些依賴項(xiàng) 對(duì)于每個(gè)命名的包或包模式儒老,get必須決定使用相應(yīng)模塊的哪個(gè)版本蝴乔。默認(rèn)情況下,get會(huì)查找最新的標(biāo)記版本驮樊,如v0.4.5或v1.2.3; 如果沒有標(biāo)記的發(fā)布版本薇正,get將查找最新的標(biāo)記的預(yù)發(fā)布版本片酝,如v0.0.1-pre1; 如果根本沒有標(biāo)記的版本,get將查找最新的已知提交挖腰。如果在更高版本(例如雕沿,比最新版本更新的預(yù)發(fā)行版)中還不需要該模塊,則get將使用它查找的版本猴仑。否則审轮,get將使用當(dāng)前所需的版本
第二步是下載(如果需要)、構(gòu)建和安裝命名包 如果參數(shù)命名的是模塊而不是包(因?yàn)槟K的根目錄中沒有g(shù)o源代碼)辽俗,則會(huì)跳過(guò)該參數(shù)的安裝步驟疾渣,而不會(huì)導(dǎo)致構(gòu)建失敗
編譯安裝包和依賴項(xiàng) 使用方法
go install [-i] [build flags] [packages]
可執(zhí)行文件安裝在由GOBIN環(huán)境變量命名的目錄中,如果未設(shè)置GOPATH環(huán)境變量崖飘,則默認(rèn)為HOME/go/bin; GOROOT/bin或GOBIN中
禁用module-aware模式時(shí),其他軟件包將安裝在目錄GOOS_$GOARCH中; 啟用module-aware模式時(shí)朱浴,將構(gòu)建并緩存其他包吊圾,但不安裝。-i標(biāo)志還安裝命名包的依賴項(xiàng)
列出包或模塊 使用方法
go list [-f format] [-json] [-m] [list flags] [build flags] [packages]
list列出了命名包翰蠢,每行一個(gè)项乒。最常用的標(biāo)志是-f和-json,它們控制為每個(gè)包打印的輸出的形式梁沧。-f標(biāo)志
使用包模板的語(yǔ)法指定列表的備用格式檀何,傳遞給模板的結(jié)構(gòu)形如
type Package struct {
Dir string // 包含包源代碼的目錄
ImportPath string // 包在目錄中的導(dǎo)入路徑
ImportComment string // package語(yǔ)句的import注釋中的路徑
Name string // 包名稱
Doc string // 包文檔字符串
Target string // 安裝路徑
Shlib string // 包含此包的共享庫(kù)(僅在-linkshared時(shí)設(shè)置)
Goroot bool // 這個(gè)包在GOROOT目錄下嗎?
Standard bool // 這個(gè)包是標(biāo)準(zhǔn)go庫(kù)的一部分嗎?
Stale bool // `go install`對(duì)這個(gè)包有什么作用碼?
StaleReason string // explanation for Stale==true
Root string // 包含這個(gè)包的GOROOT或GOPATH目錄
ConflictDir string // $GOPATH中的這個(gè)目錄shadows dir
BinaryOnly bool // binary-only package (no longer supported)
ForTest string // package is only for use in named test
Export string // file containing export data (when using -export)
Module *Module // info about package's containing module, if any (can be nil)
Match []string // command-line patterns matching this package
DepOnly bool // package is only a dependency, not explicitly listed
// Source files
GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
CgoFiles []string // .go source files that import "C"
CompiledGoFiles []string // .go files presented to compiler (when using -compiled)
IgnoredGoFiles []string // .go source files ignored due to build constraints
CFiles []string // .c source files
CXXFiles []string // .cc, .cxx and .cpp source files
MFiles []string // .m source files
HFiles []string // .h, .hh, .hpp and .hxx source files
FFiles []string // .f, .F, .for and .f90 Fortran source files
SFiles []string // .s source files
SwigFiles []string // .swig files
SwigCXXFiles []string // .swigcxx files
SysoFiles []string // .syso object files to add to archive
TestGoFiles []string // _test.go files in package
XTestGoFiles []string // _test.go files outside package
// Cgo directives
CgoCFLAGS []string // cgo: flags for C compiler
CgoCPPFLAGS []string // cgo: flags for C preprocessor
CgoCXXFLAGS []string // cgo: flags for C++ compiler
CgoFFLAGS []string // cgo: flags for Fortran compiler
CgoLDFLAGS []string // cgo: flags for linker
CgoPkgConfig []string // cgo: pkg-config names
// Dependency information
Imports []string // import paths used by this package
ImportMap map[string]string // map from source import to ImportPath (identity entries omitted)
Deps []string // all (recursively) imported dependencies
TestImports []string // imports from TestGoFiles
XTestImports []string // imports from XTestGoFiles
// Error information
Incomplete bool // this package or a dependency has an error
Error *PackageError // error loading package
DepsErrors []*PackageError // errors loading dependencies
}
下面記錄的其他列表標(biāo)志控制更具體的細(xì)節(jié)
模塊維護(hù) go mod提供對(duì)模塊操作的訪問(wèn),使用方法如下所示
go mod <command> [arguments]
注意廷支,所有g(shù)o命令都內(nèi)置了對(duì)模塊的支持埃碱,而不僅僅是“go mod”。例如酥泞,日常添加砚殿、刪除、升級(jí)和降級(jí)依賴項(xiàng)都應(yīng)該使用“go get”完成芝囤。command列表如下
下載模塊到本地緩存 使用方法如下
go mod download [-json] [modules]
下載命名模塊似炎,可以是選擇主模塊依賴項(xiàng)的模塊模式,也可以是path@version格式的模塊查詢悯姊。如果沒有參數(shù)羡藐,download將應(yīng)用于主模塊的所有依賴項(xiàng)
go命令將在正常執(zhí)行期間根據(jù)需要自動(dòng)下載模塊∶跣恚“go mod download”命令主要用于預(yù)填充本地緩存或計(jì)算go模塊代理
從工具或腳本編輯go.mod 使用方法如下
go mod edit [editing flags] [go.mod]
編輯提供了一個(gè)用于編輯go.mod的命令行接口仆嗦,主要用于工具或腳本。它只讀取go.mod先壕,不查找有關(guān)模塊的信息瘩扼。默認(rèn)情況下谆甜,edit讀取和寫入主模塊的go.mod文件,但可以在編輯標(biāo)志后指定其他目標(biāo)文件集绰。編輯標(biāo)志指定一些列編輯操作
打印模塊需求圖 使用方法如下
go mod graph
圖以文本形式打印模塊需求圖(應(yīng)用的替換)规辱。輸出中的每一行都有兩個(gè)空格分隔的字段:一個(gè)模塊及其一個(gè)需求。每個(gè)模塊都被標(biāo)識(shí)為path@version格式的字符串栽燕,但主模塊沒有@version后綴
在當(dāng)前目錄下初始化新的模塊 使用方法
go mod init [module]
init初始化并將新go.mod寫入當(dāng)前目錄罕袋,實(shí)際上創(chuàng)建一個(gè)新的模塊,該模塊以當(dāng)前目錄為根
添加缺失的模塊并移除未使用的模塊 使用方法如下
go mod tidy [-v]
tidy確保go.mod與模塊中的源代碼匹配碍岔。它增加了構(gòu)建當(dāng)前模塊的包和依賴項(xiàng)所需的任何缺少的模塊浴讯,并且移除未使用的模塊。它還將添加任何缺少項(xiàng)的go.sum并刪除任何不必要的項(xiàng)
-v標(biāo)志導(dǎo)致tidy將有關(guān)已刪除模塊的信息打印到標(biāo)準(zhǔn)錯(cuò)誤
生成依賴項(xiàng)的自動(dòng)生成副本 使用說(shuō)明
go mod vendor [-v]
vendor重置主模塊的vendor目錄蔼啦,以包含構(gòu)建和測(cè)試所有主模塊包所需的所有包兰珍。它不包括vendored的測(cè)試代碼
-v標(biāo)志將vendor提供的模塊和包的名稱打印為標(biāo)準(zhǔn)錯(cuò)誤
驗(yàn)證依賴項(xiàng)是否具有預(yù)期內(nèi)容 使用說(shuō)明
go mod verify
驗(yàn)證檢查當(dāng)前模塊(存儲(chǔ)在本地下載的源緩存中)的依賴項(xiàng)在下載后是否未被修改。如果所有模塊都未修改询吴,驗(yàn)證打印“all modules verified.”,否則它報(bào)告哪些模塊已被更改亮元,并導(dǎo)致“go mod”以非零狀態(tài)退出
解釋為什么需要包或模塊 使用說(shuō)明
go mod why [-m] [-vendor] packages...
why在導(dǎo)入圖中顯示從主模塊到列出的每個(gè)包的最短路徑猛计。如果給定了-m標(biāo)志,why將參數(shù)視為模塊列表爆捞,并在每個(gè)模塊中找到指向任何包的路徑奉瘤。默認(rèn)情況下,why查詢與“go list all”匹配的包的graph煮甥,其中包括可訪問(wèn)包的測(cè)試盗温。-vendor標(biāo)志導(dǎo)致排除依賴項(xiàng)測(cè)試的原因
編譯并運(yùn)行g(shù)o程序 使用說(shuō)明
go run [build flags] [-exec xprog] package [arguments...]
run編譯并運(yùn)行名為main的go包。通常成肘,包被指定為來(lái)自單個(gè)目錄的.go源文件列表卖局,但它也可能是與單個(gè)已知包匹配的導(dǎo)入路徑、文件系統(tǒng)路徑或模式双霍,如“go run.”或“go run my/cmd”
默認(rèn)情況下砚偶,“go run”直接運(yùn)行編譯后的二進(jìn)制文件:“a.out arguments…”。如果給定了-exec標(biāo)志洒闸,“go run”使用xprog調(diào)用二進(jìn)制文件xprog a.out arguments...
測(cè)試包 使用說(shuō)明
go test [build/test flags] [packages] [build/test flags & test binary flags]
go test
重新編譯每個(gè)包以及名稱與文件模式*_test.go
匹配的任何文件染坯。這些附加文件可以包含test functions、benchmark functions和example functions丘逸。每個(gè)列出的包都會(huì)導(dǎo)致執(zhí)行單獨(dú)的測(cè)試二進(jìn)制文件单鹿。文件名以_
開頭的文件(包括_test.go
)或.
被忽略
用后綴_test
聲明包的測(cè)試文件將被編譯為單獨(dú)的包,然后與主測(cè)試二進(jìn)制連接并運(yùn)行深纲。go工具將會(huì)忽略名為testdata
的目錄仲锄,使其可以保存測(cè)試所需的輔助數(shù)據(jù)
go test的兩種不同運(yùn)行模式
- 本地目錄模式劲妙,在沒有包參數(shù)(例如,“go test”或“go test-v”)的情況下調(diào)用go test時(shí)發(fā)生昼窗。在此模式下是趴,go test編譯當(dāng)前目錄中包的源碼和測(cè)試文件,然后運(yùn)行生成的測(cè)試二進(jìn)制文件澄惊。在此模式下唆途,將禁用緩存。在包測(cè)試完成后掸驱,go測(cè)試打印一個(gè)顯示測(cè)試狀態(tài)的“摘要行”(“OK”或“FAIL”)肛搬、包名和測(cè)試的時(shí)間
- 包列表模式,在使用顯式包參數(shù)(例如“go test math”毕贼、“go test ./…”温赔、“go test”)調(diào)用go test時(shí)發(fā)生。在此模式下鬼癣,go test編譯并測(cè)試命令行中列出的每個(gè)包陶贼。如果包測(cè)試通過(guò),則go測(cè)試只打印最終的“OK”摘要行待秃。如果包測(cè)試失敗拜秧,go test將打印完整的測(cè)試輸出。如果使用-bench或-v標(biāo)志調(diào)用章郁,go測(cè)試打印完整的輸出枉氮,甚至通過(guò)傳遞包測(cè)試,以便顯示請(qǐng)求的基準(zhǔn)測(cè)試結(jié)果或冗長(zhǎng)日志記錄暖庄。所有列出的包測(cè)試完成并打印輸出后聊替,如果存在任何一個(gè)包測(cè)試失敗,go test將打印最終“FAIL”狀態(tài)
僅在包列表模式下培廓,go test緩存成功的包測(cè)試結(jié)果惹悄,以避免不必要的重復(fù)運(yùn)行測(cè)試。當(dāng)測(cè)試結(jié)果可以從緩存中恢復(fù)時(shí)肩钠,go test將重新顯示以前的輸出俘侠,而不是再次運(yùn)行測(cè)試二進(jìn)制文件。當(dāng)發(fā)生這種情況時(shí)蔬将,go測(cè)試打印(緩存)代替匯總行中測(cè)試花費(fèi)的時(shí)間
運(yùn)行特定的go工具 使用方式說(shuō)明
go tool [-n] command [args...]
tool運(yùn)行由參數(shù)標(biāo)識(shí)的go tool命令爷速,-n標(biāo)志不帶參數(shù)地打印已知工具的列表
go版本信息 使用說(shuō)明
go version [-m] [-v] [file ...]
go version報(bào)告用于構(gòu)建每個(gè)可執(zhí)行文件的go版本。如果命令行中沒有命名文件霞怀,則go version將打印其自己的版本信息; 如果目錄被命名惫东,go version將遍歷該目錄,遞歸地查找識(shí)別的go二進(jìn)制文件并報(bào)告它們的版本。默認(rèn)情況下廉沮,go version不會(huì)報(bào)告在目錄掃描期間發(fā)現(xiàn)的無(wú)法識(shí)別的文件
-v標(biāo)志 報(bào)告無(wú)法識(shí)別的文件
-m標(biāo)志 go version在可用時(shí)打印每個(gè)可執(zhí)行文件的嵌入模塊版本信息颓遏。在輸出中,模塊信息由版本行后面的多行組成滞时,每行由一個(gè)前導(dǎo)制表符縮進(jìn)
報(bào)告包中可能出現(xiàn)的錯(cuò)誤 使用方法說(shuō)明
go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]
vet對(duì)由導(dǎo)入路徑命名的包運(yùn)行g(shù)o vet命令
構(gòu)建模式
go build
和go install
命令采用-buildmode參數(shù)叁幢,該參數(shù)指示要生成哪種類型的對(duì)象文件。當(dāng)前支持的值為
環(huán)境變量
go命令及其調(diào)用的工具用于配置參考環(huán)境變量坪稽。如果環(huán)境變量未設(shè)置曼玩,則go命令使用合理的默認(rèn)設(shè)置。要查看變量<NAME>的有效設(shè)計(jì)可以運(yùn)行go env <NAME>
; 要更改變量<NAME>的默認(rèn)設(shè)計(jì)窒百,運(yùn)行命令go env -w <NAME>=<VALUE>
通用環(huán)境變量
用于cgo的環(huán)境變量
特定于體系結(jié)構(gòu)的環(huán)境變量
特殊用途的環(huán)境變量
go env
中提供但未從環(huán)境中讀取的其他信息
邏輯和性能診斷工具
go生態(tài)系統(tǒng)提供了大量的API和工具來(lái)診斷go程序中的邏輯和性能問(wèn)題黍判,這一節(jié)是對(duì)這些可用工具的總結(jié)
診斷解決方案可以分為以下幾類
- 性能分析 這類工具用于分析go程序的復(fù)雜性和成本,例如通過(guò)它的內(nèi)存使用和頻繁調(diào)用的函數(shù)來(lái)標(biāo)識(shí)go程序的開銷部分
- 追蹤 是一種在調(diào)用或用戶請(qǐng)求的整個(gè)生命周期中檢測(cè)代碼以分析延遲的方法篙梢,它提供了每個(gè)組件對(duì)系統(tǒng)的總延遲概述顷帖,可以跨越多個(gè)go進(jìn)程進(jìn)行
- 調(diào)試 允許我們暫停go程序并檢查其執(zhí)行。程序狀態(tài)和流程可以通過(guò)調(diào)試來(lái)驗(yàn)證
- 運(yùn)行時(shí)統(tǒng)計(jì)和事件 運(yùn)行時(shí)統(tǒng)計(jì)和事件的收集和分析為go程序的健康提供了高層次的概述渤滞。尖峰/度量的監(jiān)控指標(biāo)有助于識(shí)別吞吐量贬墩、利用率和性能的變化
Tips 一些診斷工具可能相互干擾。例如妄呕,精準(zhǔn)內(nèi)存剖析可能影響CPU性能分析的準(zhǔn)確性陶舞、goroutine阻塞分析會(huì)影響調(diào)度器跟蹤。因此趴腋,單獨(dú)使用工具獲取更精確的信息
性能分析 對(duì)于識(shí)別昂貴的或頻繁調(diào)用的代碼段非常有用。go運(yùn)行時(shí)以pprof可視化工具提供所期望格式的性能分析數(shù)據(jù)论咏。在測(cè)試期間优炬,也可以通過(guò)go test或net/http/pprof包中提供的endpoints來(lái)收集性能分析數(shù)據(jù)
由runtime/pprof預(yù)定義配置文件
- cpu 決定了程序在actively狀態(tài)(而不是在sleeping或waiting I/O)時(shí)花費(fèi)的cpu時(shí)間
- heap 報(bào)告內(nèi)存分配示例;用于監(jiān)視當(dāng)前和歷史內(nèi)存使用情況厅贪,并檢查內(nèi)存泄漏
- threadcreate 報(bào)告程序中引導(dǎo)創(chuàng)建新線程的部分
- goroutine 報(bào)告當(dāng)前所有g(shù)oroutine的堆棧跟蹤
- block 顯示goroutine阻塞等待同步原語(yǔ)(包括timer channels)蠢护,block profile默認(rèn)為未啟用狀態(tài),使用runtime.SetBlockProfileRate可以啟用它
- mutex 報(bào)告鎖爭(zhēng)用养涮。當(dāng)您認(rèn)為由于互斥爭(zhēng)用導(dǎo)致CPU未充分利用時(shí)葵硕,請(qǐng)使用此profile。默認(rèn)情況下mutex profile處于未啟用狀態(tài)贯吓,通過(guò)runtime.SetMutexProfileFraction可以啟用它
其他分析器 在Linux上懈凹,可以使用perf工具分析go程序,perf可以配置和解開cgo/SWIG代碼和內(nèi)核悄谐,因此可以深入了解native/kernel性能瓶頸; 在MacOS上介评,可以使用Instruments分析go程序
生產(chǎn)服務(wù)性能分析 分析生產(chǎn)中的程序是安全的,但是啟用某些profile(例如CPU profile)會(huì)增加成本。您可能想要定期分析生產(chǎn)服務(wù)性能問(wèn)題们陆,特別是在具有單個(gè)進(jìn)程的多個(gè)副本的系統(tǒng)中寒瓦,周期性地隨機(jī)挑選一個(gè)副本是安全的選擇。選擇一個(gè)生產(chǎn)進(jìn)程坪仇,每隔Y秒分析并保存它的結(jié)果以進(jìn)行可視化分析杂腰;然后定期重復(fù)∫挝模可以手動(dòng)和/或自動(dòng)檢查結(jié)果以發(fā)現(xiàn)問(wèn)題喂很。性能收集可能相互干擾,因此建議每次只收集單個(gè)概要文件
可視化數(shù)據(jù)分析方法 go使用go tool pprof
工具提供text雾袱、graph和callgrind可視化
自定義profile go用戶可以通過(guò)運(yùn)行時(shí)提供的pprof.Profile創(chuàng)建他們的自定義配置文件恤筛,并使用現(xiàn)有的工具來(lái)檢查它們。如下示例將監(jiān)聽7777端口并以 /custom_debug_path/profile
endpoint芹橡,為pprof.Profile提供服務(wù)
package main
import (
"log"
"net/http"
"net/http/pprof"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
log.Fatal(http.ListenAndServe(":7777", mux))
}
追蹤 這是一種在調(diào)用鏈的整個(gè)生命周期中檢測(cè)代碼以分析時(shí)延的方法毒坛,go提供golang.org/x/net/trace包作為每個(gè)go節(jié)點(diǎn)的最小跟蹤后端,并用一個(gè)簡(jiǎn)單的dashboard提供一個(gè)最小的檢測(cè)庫(kù)林说,go還提供了一個(gè)可執(zhí)行的Tracer來(lái)追蹤間隔期間內(nèi)運(yùn)行時(shí)事件煎殷。追蹤可以為我們提供
- 檢測(cè)并分析go進(jìn)程中的應(yīng)用程序延遲
- 在一個(gè)很長(zhǎng)的調(diào)用鏈中測(cè)量特定調(diào)用的成本
- 找出利用率并改進(jìn)性能。沒有跟蹤數(shù)據(jù)腿箩,瓶頸并不總是顯而易見
在單體系統(tǒng)中豪直,從程序的構(gòu)建塊收集診斷數(shù)據(jù)相對(duì)容易,所有模塊都在一個(gè)進(jìn)程中珠移,并共享公共資源來(lái)報(bào)告日志弓乙、錯(cuò)誤和其他診斷信息。一旦系統(tǒng)由單體進(jìn)程擴(kuò)展到分布式微服務(wù)钧惧,就很難定位從前端Web服務(wù)器到所有后臺(tái)的調(diào)用暇韧,以及響應(yīng)返回給用戶。這也是分布式追蹤在測(cè)試和分析生產(chǎn)系統(tǒng)方面發(fā)揮重要作用的地方
分布式追蹤是一種在用戶請(qǐng)求的整個(gè)生命周期中檢測(cè)代碼以分析延遲的方法浓瞪。當(dāng)系統(tǒng)是分布式的懈玻,并且傳統(tǒng)的分析和調(diào)試工具無(wú)法擴(kuò)展時(shí),您可能希望使用分布式跟蹤工具來(lái)分析用戶請(qǐng)求和RPC的性能乾颁。分布式追蹤系統(tǒng)是我們能夠
- 在大型系統(tǒng)中檢測(cè)并分析應(yīng)用程序延遲
- 跟蹤用戶請(qǐng)求生命周期內(nèi)的所有RPC涂乌,并查看僅在生產(chǎn)中可見的集成問(wèn)題
- 找出可以應(yīng)用于我們系統(tǒng)的性能改進(jìn)。在跟蹤數(shù)據(jù)收集之前英岭,許多瓶頸是不明顯的
go生態(tài)系統(tǒng)為每個(gè)追蹤系統(tǒng)提供了不同的分布式跟蹤庫(kù)和對(duì)后端透明的庫(kù)
調(diào)試 調(diào)試是識(shí)別程序錯(cuò)誤行為的過(guò)程盐肃,調(diào)試器允許我們了解程序的執(zhí)行流程和當(dāng)前狀態(tài)谁不。go用戶主要使用以下調(diào)試器
- **Delve ** 作為go編程語(yǔ)言的調(diào)試器骡澈,它支持go的運(yùn)行時(shí)概念和內(nèi)置類型扭倾。Delve正試圖成為一個(gè)功能齊全的可靠的go程序調(diào)試器
- GDB go通過(guò)標(biāo)準(zhǔn)go編譯器和gccgo提供GDB支持。堆棧管理、線程和運(yùn)行時(shí)包含不同于執(zhí)行模型的方面荧库,GDB可能混淆調(diào)試器堰塌,即使程序是用gccgo編譯的。盡管GDB可以用來(lái)調(diào)試go程序分衫,但它并不理想场刑,可能會(huì)造成混亂
運(yùn)行時(shí)統(tǒng)計(jì)和事件 運(yùn)行時(shí)提供用戶內(nèi)部事件的統(tǒng)計(jì)和報(bào)告,以便在運(yùn)行時(shí)級(jí)別診斷性能和使用問(wèn)題蚪战。用戶可以監(jiān)視這些統(tǒng)計(jì)信息牵现,以便更好地了解go程序的整體健康和性能。一些經(jīng)常監(jiān)視的統(tǒng)計(jì)數(shù)據(jù)和狀態(tài)
- runtime.ReadMemStats 報(bào)告與堆分配和垃圾收集相關(guān)的度量指標(biāo)邀桑。內(nèi)存統(tǒng)計(jì)對(duì)于監(jiān)視進(jìn)程消耗多少內(nèi)存資源瞎疼、進(jìn)程是否可以充分利用內(nèi)存以及捕獲內(nèi)存泄漏是有用的
- debug.ReadGCStats 讀取垃圾收集的統(tǒng)計(jì)信息。查看gc暫停上花費(fèi)了多少資源是很有用的壁畸。它還報(bào)告了垃圾收集器暫停和暫停時(shí)間百分比的時(shí)間線
- debug.Stack 返回當(dāng)前堆棧跟蹤贼急,堆棧跟蹤對(duì)于查看當(dāng)前正在運(yùn)行的goroutine的數(shù)量、它們正在執(zhí)行的操作以及它們是否被阻止非常有用
- debug.WriteHeapDump 暫停所有g(shù)oroutine的執(zhí)行并允許您將堆轉(zhuǎn)儲(chǔ)到文件捏萍。堆轉(zhuǎn)儲(chǔ)是在給定時(shí)間內(nèi)go進(jìn)程內(nèi)存的快照太抓。它包含所有分配的對(duì)象以及goroutine、finalizers等
- runtime.NumGoroutine 返回當(dāng)前goroutine的數(shù)目令杈∽叩校可以監(jiān)視該值以查看是否有足夠的goroutine供使用,或檢測(cè)goroutine泄漏
go附帶運(yùn)行時(shí)Execution Tracer來(lái)捕獲大量運(yùn)行時(shí)事件逗噩。調(diào)度掉丽、SysCall、垃圾回收异雁、堆大小和其他事件由運(yùn)行時(shí)收集捶障,并可用于go工具跟蹤可視化。Tracer可用于
- 了解goroutine如何執(zhí)行
- 了解一些核心運(yùn)行時(shí)事件片迅,例如GC
- 識(shí)別并行性差的執(zhí)行
小結(jié)
go提供了豐富的命令行和工具残邀,在日常運(yùn)維開發(fā)中熟練使用命令/工具能夠大大提升效率皆辽。本文是關(guān)于命令行和常用工具的簡(jiǎn)單總結(jié)柑蛇,希望能對(duì)您有所幫助