Go生態系統提供了一整套用於診斷Go程序中的邏輯和性能問題的API和工具。該篇文章總結了可用的工具,並幫助Go用戶針對他們的特定問題選擇合適的工具。html
診斷解決方案能夠分爲如下幾類:前端
注意:某些診斷工具可能會相互干擾。例如,內存分析會影響CPU profiles,goroutine 阻塞分析會影響調度程序跟蹤。一次只使用一種工具以得到更精確的信息。git
分析對於識別消耗資源嚴重或常常調用的代碼段頗有用。 Go運行時以pprof可視化工具所需的格式提供概要分析數據。能夠在測試過程當中經過go test或 net/http/pprof 程序包中提供的端點收集性能分析數據。用戶須要收集性能分析數據並使用pprof工具來過濾和可視化代碼路徑。github
runtime/pprof 軟件包提供的預約義profiles:golang
我還可使用哪些其餘分析器來分析Go程序?web
在Linux上,可使用perf工具來分析Go程序。 Perf能夠分析和解散cgo /SWIG代碼和內核,所以深刻了解本機/內核性能瓶頸可能頗有用。在macOS上,Instruments套件可用於profile Go程序。數據庫
我能夠profile個人生產服務嗎?編程
是。在生產環境中對程序進行概要分析是安全的,可是啓用某些概要文件(例如CPU概要文件)會增長成本。您應該指望看到性能降低。能夠經過在生產以前打開Profiler來測量Profiler的開銷來估算性能損失。後端
您可能須要按期分析生產服務。特別是在具備單個進程多個副本的系統中,按期選擇隨機副本是一個安全的選擇。選擇一個生產過程,每隔Y秒將其概要分析X秒,並保存結果以進行可視化和分析;而後按期重複。能夠手動或自動查看結果以發現問題。profile的收集可能會相互干擾,所以建議一次僅收集一個profile。安全
可視化分析數據的最佳方法是什麼?
Go工具使用go tool pprof提供profile數據的文本,圖形和callgrind可視化。閱讀Profiling Go程序以查看它們的運行狀況。
以文本形式列出最消耗資源的調用
將最消耗資源的調用可視化爲圖表
Weblist視圖在HTML頁面中逐行顯示源代碼最消耗資源的部分。在下面的示例中,運行時花費了530毫秒。runtime.concatstrings和清單中列出了每行的成本。
將最消耗資源的調用可視化爲weblist
可視化輪廓數據的另外一種方法是火焰圖。火焰圖使您能夠在特定的祖先路徑中移動,所以能夠放大/縮小代碼的特定部分。上游pprof支持火焰圖。
我是否限於內置profiles?
除了運行時提供的功能外,Go用戶還能夠經過pprof.Profile建立其自定義profile,並使用現有工具進行檢查。
我能夠在其餘路徑和端口上提供事件探查器處理程序(/debug/pprof/ ...)嗎?
是。 net/http/pprof軟件包默認狀況下將其處理程序註冊到默認的多路複用器,可是您也可使用從軟件包中導出的處理程序本身註冊它們。
例如,如下示例將在 /custom_debug_path/profile上的:7777上提供pprof.Profile處理程序:
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)) }
跟蹤是一種工具代碼,能夠分析整個調用鏈的整個生命週期中的延遲。 Go提供golang.org/x/net/trace軟件包做爲每一個Go節點的最小跟蹤後端,並提供帶有簡單儀表板的最小檢測庫。 Go還提供了一個執行跟蹤器,以跟蹤一個間隔內的運行時事件。
Tracing 能夠在如下方面幫助到咱們:
在單片系統中,從程序的構建塊中收集診斷數據相對容易。全部模塊都生活在一個過程當中,並共享公共資源來報告日誌,錯誤和其餘診斷信息。一旦您的系統超出了單個進程並開始分佈,就很難跟蹤從前端Web服務器到其全部後端的調用,直到將響應返回給用戶爲止。在這裏,分佈式跟蹤對儀器和分析生產系統起着重要做用。
分佈式跟蹤是一種工具代碼,能夠分析用戶請求整個生命週期中的延遲。當系統是分佈式的而且常規的性能分析和調試工具沒法擴展時,您可能但願使用分佈式跟蹤工具來分析用戶請求和RPC的性能。
分佈式跟蹤在如下幾個方面能夠幫助到咱們:
Go生態系統爲每一個跟蹤系統和與後端無關的數據庫提供了各類分佈式跟蹤庫。
有沒有一種方法能夠自動攔截每一個函數調用並建立跟蹤?
Go沒法提供一種自動攔截每一個函數調用並建立跟蹤範圍的方法。您須要手動檢測代碼以建立,結束和註釋跨度。
我應該如何在Go庫中傳播跟蹤頭?
您能夠在context.Context中傳播跟蹤標識符和標記。業界尚無規範的跟蹤鍵或跟蹤頭的通用表示形式。每一個跟蹤提供者都有責任在其Go庫中提供傳播實用程序。
標準庫或運行時中還有哪些其餘低級事件能夠包含在跟蹤中?
標準庫和運行時正嘗試公開一些其餘API,以在發生低級內部事件時進行通知。例如,httptrace.ClientTrace提供API以在傳出請求的生命週期中跟蹤低級事件。正在進行中的工做是從運行時執行跟蹤器中檢索低級運行時事件,並容許用戶定義和記錄其用戶事件。
調試是肯定程序行爲異常的過程。調試器使咱們可以瞭解程序的執行流程和當前狀態。調試有幾種樣式。本節僅關注將調試器附加到程序和core dump調試。
Go用戶一般使用如下調試器:
調試器與Go程序的配合狀況如何?
gc編譯器執行優化,例如函數內聯和變量註冊。這些優化有時會使調試器的調試更加困難。正在進行不斷的努力來改善爲優化的二進制文件生成的DWARF信息的質量。在這些改進可用以前,咱們建議在構建要調試的代碼時禁用優化。如下命令生成沒有編譯器優化的軟件包:
$ go build -gcflags=all="-N -l"
做爲改進工做的一部分,Go 1.10引入了新的編譯器標誌-dwarflocationlists。該標誌使編譯器添加位置列表,以幫助調試器使用優化的二進制文件。如下命令使用DWARF位置列表構建具備優化的軟件包:
$ go build -gcflags="-dwarflocationlists=true"
推薦的調試器用戶界面是什麼?
儘管delve和gdb都提供了CLI,可是大多數編輯器集成和IDE都提供了特定於調試的用戶界面。
可使用Go程序進行過後調試嗎?
core dump文件是一個文件,其中包含正在運行的進程的內存dump及其進程狀態。它主要用於程序的過後調試,並在程序仍在運行時瞭解其狀態。這兩種狀況使core dump的調試成爲進行過後分析和分析生產服務的良好診斷工具。能夠從Go程序中獲取core文件,並使用delve或gdb進行調試,有關逐步指南,請參見core dump調試頁面。
運行時爲用戶提供內部事件的統計信息和報告,以在運行時級別診斷性能和利用率問題。
用戶能夠監視這些統計信息,以更好地瞭解Go程序的總體運行情況和性能。一些常常監視的統計信息和狀態:
Go附帶了一個運行時執行跟蹤程序,以捕獲各類運行時事件。調度,系統調用,垃圾回收,堆大小和其餘事件由運行時收集,而且能夠經過go工具跟蹤進行可視化。執行跟蹤器是檢測延遲和利用率問題的工具。您能夠檢查CPU的利用率,以及什麼時候網絡鏈接或系統調用會致使goroutine搶佔。
跟蹤器在一下幾個方面能夠幫助到您:
可是,這對於識別熱點(例如分析過多的內存或CPU使用率的緣由)不是很好。而是首先使用分析工具來解決它們。
上面的go工具跟蹤可視化顯示執行開始良好,而後序列化了。它代表可能存在致使瓶頸的共享資源的鎖爭用。
請參閱go tool trace以收集和分析運行時跟蹤。
若是相應地設置了GODEBUG環境變量,則運行時還會發出事件和信息。
GODEBUG環境變量可用於在標準庫和運行時中禁用指令集擴展。