Golang(三)命令行工具集

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)只能通過go tool子命令訪問。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ù)是來自單個(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ì)象,僅用于檢查包是否可編譯

go build

刪除對(duì)象文件和緩存文件 用法如下

go clean [clean flags] [build flags] [packages]

clean從包源目錄中刪除對(duì)象文件。go命令在一個(gè)臨時(shí)目錄中構(gòu)建大多數(shù)對(duì)象,因此go clean主要關(guān)注其他go工具或通過手動(dòng)調(diào)用go build留下的對(duì)象文件

go clean

展示包或符號(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 doc

打印go環(huán)境信息 用法

go env [-json] [-u] [-w] [var ...]

默認(rèn)情況下,env將信息打印為shell腳本(在windows上,是批處理文件)。如果一個(gè)或多個(gè)變量名作為參數(shù)給定,env將在其自己的行上打印每個(gè)命名變量的值

go env

更新包以使用新的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

通過處理源碼生成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)志在處理過程中打印包和文件的名稱; -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ì)跳過該參數(shù)的安裝步驟,而不會(huì)導(dǎo)致構(gòu)建失敗

go get

編譯安裝包和依賴項(xiàng) 使用方法

go install [-i] [build flags] [packages]

可執(zhí)行文件安裝在由GOBIN環(huán)境變量命名的目錄中,如果未設(shè)置GOPATH環(huán)境變量,則默認(rèn)為GOPATH/bin或HOME/go/bin; GOROOT中的可執(zhí)行文件安裝在GOROOT/bin或GOTOOLDIR中,而不是GOBIN中

禁用module-aware模式時(shí),其他軟件包將安裝在目錄GOPATH/pkg/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é)

go list

模塊維護(hù) go mod提供對(duì)模塊操作的訪問,使用方法如下所示

go mod <command> [arguments]

注意,所有g(shù)o命令都內(nèi)置了對(duì)模塊的支持,而不僅僅是“go mod”。例如,日常添加、刪除、升級(jí)和降級(jí)依賴項(xiàng)都應(yīng)該使用“go get”完成。command列表如下

go mod

下載模塊到本地緩存 使用方法如下

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 edit

打印模塊需求圖 使用方法如下

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)生成副本 使用說明

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)容 使用說明

go mod verify

驗(yàn)證檢查當(dāng)前模塊(存儲(chǔ)在本地下載的源緩存中)的依賴項(xiàng)在下載后是否未被修改。如果所有模塊都未修改,驗(yàn)證打印“all modules verified.”,否則它報(bào)告哪些模塊已被更改,并導(dǎo)致“go mod”以非零狀態(tài)退出

解釋為什么需要包或模塊 使用說明

go mod why [-m] [-vendor] packages...

why在導(dǎo)入圖中顯示從主模塊到列出的每個(gè)包的最短路徑。如果給定了-m標(biāo)志,why將參數(shù)視為模塊列表,并在每個(gè)模塊中找到指向任何包的路徑。默認(rèn)情況下,why查詢與“go list all”匹配的包的graph,其中包括可訪問包的測(cè)試。-vendor標(biāo)志導(dǎo)致排除依賴項(xiàng)測(cè)試的原因

編譯并運(yùn)行g(shù)o程序 使用說明

go run [build flags] [-exec xprog] package [arguments...]

run編譯并運(yùn)行名為main的go包。通常,包被指定為來自單個(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è)試包 使用說明

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è)試通過,則go測(cè)試只打印最終的“OK”摘要行。如果包測(cè)試失敗,go test將打印完整的測(cè)試輸出。如果使用-bench或-v標(biāo)志調(diào)用,go測(cè)試打印完整的輸出,甚至通過傳遞包測(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í)間

go test

運(yùn)行特定的go工具 使用方式說明

go tool [-n] command [args...]

tool運(yùn)行由參數(shù)標(biāo)識(shí)的go tool命令,-n標(biāo)志不帶參數(shù)地打印已知工具的列表

go版本信息 使用說明

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)的無法識(shí)別的文件

-v標(biāo)志 報(bào)告無法識(shí)別的文件

-m標(biāo)志 go version在可用時(shí)打印每個(gè)可執(zhí)行文件的嵌入模塊版本信息。在輸出中,模塊信息由版本行后面的多行組成,每行由一個(gè)前導(dǎo)制表符縮進(jìn)

報(bào)告包中可能出現(xiàn)的錯(cuò)誤 使用方法說明

go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]

vet對(duì)由導(dǎo)入路徑命名的包運(yùn)行g(shù)o vet命令

構(gòu)建模式

go buildgo install命令采用-buildmode參數(shù),該參數(shù)指示要生成哪種類型的對(duì)象文件。當(dāng)前支持的值為

build modes

環(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)境變量

go env general-purpose

用于cgo的環(huán)境變量

go env cgo

特定于體系結(jié)構(gòu)的環(huán)境變量

go env arch

特殊用途的環(huán)境變量

go env special

go env中提供但未從環(huán)境中讀取的其他信息

go env additional

邏輯和性能診斷工具

go生態(tài)系統(tǒng)提供了大量的API和工具來診斷go程序中的邏輯和性能問題,這一節(jié)是對(duì)這些可用工具的總結(jié)

診斷解決方案可以分為以下幾類

  • 性能分析 這類工具用于分析go程序的復(fù)雜性和成本,例如通過它的內(nèi)存使用和頻繁調(diào)用的函數(shù)來標(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)和流程可以通過調(diào)試來驗(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è)試期間,也可以通過go test或net/http/pprof包中提供的endpoints來收集性能分析數(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),通過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ù)性能問題,特別是在具有單個(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)問題。性能收集可能相互干擾,因此建議每次只收集單個(gè)概要文件

可視化數(shù)據(jù)分析方法 go使用go tool pprof工具提供text、graph和callgrind可視化

自定義profile go用戶可以通過運(yùn)行時(shí)提供的pprof.Profile創(chuàng)建他們的自定義配置文件,并使用現(xiàn)有的工具來檢查它們。如下示例將監(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來追蹤間隔期間內(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)程中,并共享公共資源來報(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)試工具無法擴(kuò)展時(shí),您可能希望使用分布式跟蹤工具來分析用戶請(qǐng)求和RPC的性能。分布式追蹤系統(tǒng)是我們能夠

  • 在大型系統(tǒng)中檢測(cè)并分析應(yīng)用程序延遲
  • 跟蹤用戶請(qǐng)求生命周期內(nèi)的所有RPC,并查看僅在生產(chǎ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ò)誤行為的過程,調(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通過標(biāo)準(zhǔn)go編譯器和gccgo提供GDB支持。堆棧管理、線程和運(yùn)行時(shí)包含不同于執(zhí)行模型的方面,GDB可能混淆調(diào)試器,即使程序是用gccgo編譯的。盡管GDB可以用來調(diào)試go程序,但它并不理想,可能會(huì)造成混亂

運(yùn)行時(shí)統(tǒng)計(jì)和事件 運(yùn)行時(shí)提供用戶內(nèi)部事件的統(tǒng)計(jì)和報(bào)告,以便在運(yùn)行時(shí)級(jí)別診斷性能和使用問題。用戶可以監(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ù)目??梢员O(jiān)視該值以查看是否有足夠的goroutine供使用,或檢測(cè)goroutine泄漏

go附帶運(yùn)行時(shí)Execution Tracer來捕獲大量運(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ì)您有所幫助

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 6,340評(píng)論 0 10
  • 本文簡(jiǎn)單介紹 Golang 提供的命令。我們執(zhí)行 go help [command] 可以查看具體命令的幫助信息。...
    juniway閱讀 2,233評(píng)論 0 2
  • 大多數(shù) Nginx 新手都會(huì)頻繁遇到這樣一個(gè)困惑,那就是當(dāng)同一個(gè)location配置塊使用了多個(gè) Nginx 模塊...
    SkTj閱讀 8,248評(píng)論 0 12
  • 我們都是陰溝里的蟲子,但總還是得有人仰望星空。 前一陣子有個(gè)新聞,柯潔以0:4輸給了阿爾法狗。如果你不知道柯潔是誰(shuí)...
    新月飯店大小姐閱讀 555評(píng)論 0 0
  • “財(cái)富,是你積累下來的東西,而不是你花掉的東西。” 在我們身邊,500多名富翁現(xiàn)身說法。他們不說,卻一直在...
    菜花田閱讀 667評(píng)論 1 4

友情鏈接更多精彩內(nèi)容