<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go中的程序診斷

          共 8013字,需瀏覽 17分鐘

           ·

          2021-11-30 23:44

          本文由cyningsun翻譯自Go官網(wǎng)文檔:https://golang.org/doc/diagnostics 原文地址為:https://www.cyningsun.com/07-21-2019/go-diagnostics-cn.html

          目錄

          • Introduction

          • Profiling

          • Tracing

          • Debugging

          • Runtime statistics and events

          Introduction

          Go生態(tài)系統(tǒng)提供了大量API和工具來診斷Go程序中的邏輯和性能問題。此頁面總結(jié)了可用的工具,并幫助Go用戶針對(duì)他們的特定問題選擇正確的工具。

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

          • Profiling:Profiling 工具分析Go程序的復(fù)雜性和成本,例如其內(nèi)存使用情況和頻繁調(diào)用的函數(shù),以識(shí)別Go程序的昂貴部分。
          • Tracing:Tracing 是一種檢測代碼的方法,用于分析調(diào)用或用戶請(qǐng)求的整個(gè)生命周期中的延遲。Traces 提供了每個(gè)組件對(duì)系統(tǒng)總體延遲影響的概覽。Traces 可以跨越多個(gè)Go進(jìn)程。
          • Debugging: Debugging 允許我們暫停Go程序并檢查其執(zhí)行。可以通過 debugging 驗(yàn)證程序狀態(tài)和流程。
          • Runtime statistics and events:對(duì)運(yùn)行時(shí)統(tǒng)計(jì)信息、事件的收集和分析提供了Go程序運(yùn)行狀況的高層次概覽。指標(biāo)的尖峰/下降有助于我們識(shí)別吞吐量,利用率和性能的變化。

          注意:某些診斷工具可能會(huì)相互干擾。例如,精確的 memory profiling 會(huì)扭曲 CPU profiles,而goroutine blocking profiling 會(huì)影響 scheduler trace。隔離使用工具可獲得更精確的信息。

          Profiling

          Profiling 對(duì)于識(shí)別昂貴或經(jīng)常調(diào)用的代碼段很有用。Go runtime 以 pprof 可視化工具[1]所期望的格式提供 profiling data[2]。在測試期間可以通過 go testnet/http/pprof[3] 包提供的 endpoints 收集 profiling data。用戶需要收集 profiling data 并使用 pprof 工具來過濾和可視化頂部代碼路徑。

          runtime/pprof[4] 包提供的預(yù)定義 profiles:

          • cpu: CPU profile 確定程序在活躍的消耗CPU周期(而不是在睡眠或等待I/O時(shí))花費(fèi)時(shí)間的位置。
          • heap: Heap profile 報(bào)告內(nèi)存分配樣本; 用于監(jiān)視當(dāng)前和歷史內(nèi)存使用情況,并檢查內(nèi)存泄漏。
          • threadcreate: Thread creation profile 報(bào)告程序中導(dǎo)致創(chuàng)建新OS線程的部分。
          • goroutine: Goroutine profile 報(bào)告所有當(dāng)前 goroutines 的 stack traces。
          • block: Block profile 顯示goroutine阻止等待同步原語(包括 timer channels)的位置。Block profile 默認(rèn)情況下未開啟; 使用 runtime.SetBlockProfileRate 啟用。
          • mutex: Mutex profile 報(bào)告鎖競爭。如果您認(rèn)為由于互斥競爭而未充分利用您的CPU,請(qǐng)使用此 profile。Mutex profile 默認(rèn)情況下未開啟,請(qǐng)參閱 runtime.SetMutexProfileFraction 啟用。

          我可以使用其他哪些 profilers 來介紹Go程序?

          在Linux上,perf tools[5] 可用于分析Go程序。Perf 可以 profile 和展開 cgo/SWIG 代碼和內(nèi)核,因此深入了解native/內(nèi)核性能瓶頸非常有用。在macOS上, Instruments[6] 套件可以用來 profile Go 程序。

          我可以 profile 我的生產(chǎn)環(huán)境的服務(wù)嗎?

          是的。在生產(chǎn)環(huán)境中對(duì)程序進(jìn)行 profile 是安全的,但啟用某些 profiles(例如:CPU profile)會(huì)增加消耗。您應(yīng)該會(huì)看到性能降級(jí)。在生產(chǎn)中打開探測器之前,可以通過測量 profiler 的開銷來估計(jì)性能損失。

          您可能希望定期分析您的生產(chǎn)服務(wù)。特別是在具有單進(jìn)程多副本的系統(tǒng)中,定期選擇隨機(jī)副本是安全的選擇。選擇一個(gè)生產(chǎn)服務(wù), 每隔Y秒 profile X秒并保存結(jié)果以進(jìn)行可視化和分析; 然后定期重復(fù)??梢?手動(dòng)/自動(dòng) 檢查結(jié)果以發(fā)現(xiàn)問題。profiles 收集可能會(huì)相互干擾,因此建議一次只收集一個(gè) profile。

          可視化分析數(shù)據(jù)的最佳方法是什么?

          Go tools使用 go tool pprof[7] 提供文本,圖形和 callgrind[8] 可視化的 profile data。閱讀 Profiling Go programs[9] 以查看它們的實(shí)際使用。

          pprof-text.png

          文本方式查看最大的消耗的調(diào)用



          pprof-dot.png


          圖片方式可視化最大的消耗的調(diào)用

          Weblist視圖在HTML頁面中逐行顯示源代碼最大消耗的部分。在以下示例中,530ms用于 runtime.concatstrings,每行的消耗顯示在列表中。


          pprof-weblist.png

          weblist方式可視化最大的消耗的調(diào)用

          另一種可視化輪廓數(shù)據(jù)的方法是火焰圖[10]?;鹧鎴D允許您在特定的祖先路徑中移動(dòng),因此您可以放大/縮小特定的代碼段。upstream pprof[11]支持火焰圖。


          flame.png

          火焰圖方式可視化以發(fā)現(xiàn)最昂貴的代碼路徑

          我是否僅限于內(nèi)置profiles?

          除了 runtime 提供的工具之外,Go用戶還可以通過 pprof.Profile[12] 創(chuàng)建自定義 profiles,并使用現(xiàn)有工具對(duì)其進(jìn)行檢查。

          我可以在不同的路徑和端口上提供 profiler handlers(/debug/pprof/…) 嗎?

          是的。默認(rèn)情況下, net/http/pprof 包將其 handlers 注冊(cè)到默認(rèn)的mux,但您也可以使用從包中導(dǎo)出的handler net/http/pprof注冊(cè)它們。

          例如,以下示例將在7777端口/custom_debug_path/profile上提供 pprof.Profile handler:

          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))
          }

          Tracing

          Tracing 是一種檢測代碼的方法,用于分析一系列調(diào)用的生命周期中的延遲。Go提供 golang.org/x/net/trace[13] 包作為每個(gè)Go節(jié)點(diǎn)的最小 tracing backend,并提供一個(gè)帶有簡單儀表板的最小檢測庫。Go還提供了一個(gè)執(zhí)行跟蹤器來跟蹤時(shí)間間隔內(nèi)的 runtime events。

          Tracing 使我們能夠:

          • 檢測和分析Go進(jìn)程中應(yīng)用程序延遲。
          • 衡量一長串調(diào)用中特定調(diào)用的耗時(shí)。
          • 弄清楚使用情況和性能改進(jìn)點(diǎn)。沒有tracing數(shù)據(jù),瓶頸并不總是顯而易見。

          在單機(jī)系統(tǒng)中,從程序的構(gòu)成模塊收集診斷數(shù)據(jù)相對(duì)容易。所有模塊都位于一個(gè)進(jìn)程中,并共享公共資源以報(bào)告日志,錯(cuò)誤和其他診斷信息。一旦您的系統(tǒng)超出單個(gè)進(jìn)程并開始變?yōu)榉植际?,跟蹤從前端Web服務(wù)器到其所有后端的調(diào)用,直到將響應(yīng)返回給用戶,將變得更加困難。這就是分布式 tracing 在檢測和分析生產(chǎn)系統(tǒng)方面發(fā)揮重要作用的地方。

          分布式 tracing 是一種檢測代碼的方法,用于分析用戶請(qǐng)求在整個(gè)生命周期中的延遲。當(dāng)系統(tǒng)分布式化,并且傳統(tǒng)的分析和調(diào)試工具無法scale時(shí),您可能希望使用分布式 tracing 工具來分析用戶請(qǐng)求和RPC的性能。

          分布式 tracing 使我們能夠:

          • 檢測和分析在大系統(tǒng)中的應(yīng)用延遲。
          • 跟蹤用戶請(qǐng)求生命周期內(nèi)的所有RPC,并發(fā)現(xiàn)僅在生產(chǎn)中可見的集成問題。
          • 找出可應(yīng)用于我們系統(tǒng)的性能改進(jìn)點(diǎn)。在收集 tracing 數(shù)據(jù)之前,許多瓶頸并不明顯。

          GO生態(tài)系統(tǒng)為每個(gè)跟蹤系統(tǒng)提供了不同的分布式跟蹤庫和后端無關(guān)的跟蹤庫。

          有沒有辦法自動(dòng)攔截每個(gè)函數(shù)調(diào)用并創(chuàng)建 tracing ?

          Go沒有提供自動(dòng)攔截每個(gè)函數(shù)調(diào)用和創(chuàng)建trace spans的方法。您需要手動(dòng)檢測代碼以創(chuàng)建,結(jié)束和注釋 spans。

          我應(yīng)該如何在Go庫中傳播 trace headers ?

          您可以在 context.Context[14] 傳播trace標(biāo)識(shí)符和標(biāo)記。目前行業(yè)中還沒有 trace key 的規(guī)范和 trace headers 的通用表示。每個(gè)tracing提供程序都負(fù)責(zé)在其Go庫中提供傳播工具。

          標(biāo)準(zhǔn)庫或 runtime 中的其他低級(jí)事件可以包含在 trace 中嗎?

          標(biāo)準(zhǔn)庫和 runtime 試圖公開幾個(gè)額外的API來通知低級(jí)內(nèi)部事件。例如, httptrace.ClientTrace[15] 提供API以跟蹤傳出請(qǐng)求生命周期中的低級(jí)事件。目前正在努力從 runtime execution tracer 中檢索低級(jí)運(yùn)行時(shí)事件,并允許用戶定義和記錄其用戶事件。

          Debugging

          Debugging 是識(shí)別程序錯(cuò)誤行為的過程。調(diào)試器允許我們理解程序的執(zhí)行流程和當(dāng)前狀態(tài)。有幾種調(diào)試方式;本節(jié)只關(guān)注將調(diào)試器 attach 到程序和 core dump 調(diào)試。

          GO用戶主要使用以下調(diào)試器:

          • Delve[16] :Delve是Go編程語言的調(diào)試器。它支持Go的 runtime 概念和內(nèi)置類型。Delve正試圖成為Go程序的全功能可靠調(diào)試器。
          • GDB[17] :Go通過標(biāo)準(zhǔn)Go編譯器和 Gccgo 提供 GDB 支持。堆棧管理、線程和運(yùn)行時(shí)包含的方面與 GDB 執(zhí)行模型有足夠的不同,因此可能會(huì)使調(diào)試器難以理解。即使程序是使用 gccgo 編譯的。盡管GDB可用于調(diào)試Go程序,但它并不理想,可能會(huì)造成混亂。

          調(diào)試器與 Go 程序的兼容性如何?

          gc 編譯器執(zhí)行優(yōu)化,例如函數(shù)內(nèi)聯(lián)和變量注冊(cè)。這些優(yōu)化有時(shí)會(huì)使調(diào)試器調(diào)試更困難。目前正在努力提高優(yōu)化后的二進(jìn)制文件的DWARF 信息的質(zhì)量。在這些改進(jìn)可用之前,我們建議在構(gòu)建正在調(diào)試的代碼時(shí)禁用優(yōu)化。以下命令構(gòu)建一個(gè)沒有編譯器優(yōu)化的包:

          $?go?build?-gcflags=all="-N?-l"

          作為改進(jìn)工作的一部分,Go 1.10引入了一個(gè)新的編譯器flag -dwarflocationlists。該標(biāo)志使編譯器添加位置列表,以幫助調(diào)試器使用優(yōu)化后的二進(jìn)制文件。以下命令構(gòu)建使用優(yōu)化但包含 DWARF 位置列表的包:

          $?go?build?-gcflags="-dwarflocationlists=true"

          推薦的用戶界面調(diào)試器是什么?

          盡管 delve 和 gdb 都提供了 CLI,但大多數(shù)集成編輯器和IDE都提供了特定于調(diào)試的用戶界面。

          是否可以使用Go程序進(jìn)行事后調(diào)試?

          core dump 文件是包含正在運(yùn)行的進(jìn)程及其進(jìn)程狀態(tài)的 memory dump 文件。它主要用于程序的事后調(diào)試,并了解它仍在程序運(yùn)行時(shí)的狀態(tài)。這兩種情況使 core dump 的調(diào)試成為一種良好的診斷工具,可用于事后分析和分析生產(chǎn)服務(wù)??梢詮腉o程序獲取core文件,并使用delve或gdb進(jìn)行調(diào)試,請(qǐng)參閱 core dump debugging[18] 頁面以獲取分步指南。

          Runtime statistics and events

          runtime 為用戶提供內(nèi)部事件的統(tǒng)計(jì)信息和報(bào)告,以便在 runtime 級(jí)別診斷性能和利用率問題。

          用戶可以監(jiān)控這些統(tǒng)計(jì)數(shù)據(jù),以更好地了解Go程序的整體運(yùn)行狀況和性能。一些經(jīng)常監(jiān)控的統(tǒng)計(jì)數(shù)據(jù)和狀態(tài):

          • [runtime.ReadMemStats](https://golang.org/pkg/runtime/#ReadMemStats "runtime.ReadMemStats") 報(bào)告與堆分配和垃圾回收相關(guān)的metrics。內(nèi)存統(tǒng)計(jì)信息對(duì)于監(jiān)視進(jìn)程正在消耗多少內(nèi)存資源,進(jìn)程是否可以很好地利用內(nèi)存以及捕獲內(nèi)存泄漏非常有用。
          • [debug.ReadGCStats](https://golang.org/pkg/runtime/debug/#ReadGCStats "debug.ReadGCStats") 讀取有關(guān)垃圾收集的統(tǒng)計(jì)信息。查看有多少資源用于GC暫停非常有用。它還報(bào)告垃圾收集器暫停和暫停時(shí)間百分比的 timeline。
          • [debug.Stack](https://golang.org/pkg/runtime/debug/#Stack "debug.Stack") 返回當(dāng)前 stack trace。stack trace 有助于查看當(dāng)前正在運(yùn)行的 goroutine 數(shù)量,它們正在執(zhí)行的操作,以及它們是否被阻塞。
          • [debug.WriteHeapDump](https://golang.org/pkg/runtime/debug/#WriteHeapDump "debug.WriteHeapDump") 掛起所有 goroutine 的執(zhí)行,并允許您將堆 dump 到文件中。heap dump 是給定時(shí)間Go進(jìn)程的內(nèi)存快照。它包含所有已分配的對(duì)象以及 goroutine,finalizers 等。
          • [runtime.NumGoroutine](https://golang.org/pkg/runtime#NumGoroutine "runtime.NumGoroutine") 返回當(dāng)前 goroutine 的數(shù)量??梢员O(jiān)視該值以查看是否使用了足夠的goroutine,或檢測goroutine泄漏。

          Execution tracer

          Go附帶了一個(gè)runtime execution tracer,用于捕獲各種運(yùn)行時(shí)事件。調(diào)度,系統(tǒng)調(diào)用,垃圾收集,堆大小和其他由 runtime 收集的事件,并可通過 go tool trace 進(jìn)行可視化。Execution tracer 是一種檢測延遲和利用率問題的工具。您可以檢查CPU的使用情況,以及當(dāng)網(wǎng)絡(luò)或系統(tǒng)調(diào)用成為goroutines搶占的原因。

          Tracer 使我們能夠:

          • 了解你的 goroutines 如何執(zhí)行。
          • 了解一些核心 runtime 事件,例如GC運(yùn)行。
          • 識(shí)別并行化不足的執(zhí)行。

          但是,識(shí)別熱點(diǎn)(如分析內(nèi)存過多或CPU使用率的原因)并不是很好用。首先使用 profiling tools 來解決它們。


          tracer-lock.png

          以上,go tool trace 可視化顯示執(zhí)行開始正常,然后它變得順序化。它表明可能存在共享資源的鎖競爭導(dǎo)致的瓶頸。

          請(qǐng)參閱 go tool trace[19] 以收集和分析 runtime traces。

          GODEBUG

          如果相應(yīng)地設(shè)置了 GODEBUG[20] 環(huán)境變量,Runtime 也會(huì)發(fā)出事件和信息。

          • GODEBUG=gctrace=1 在每個(gè)集合中打印垃圾收集器事件,總結(jié)收集的內(nèi)存量和暫停的長度。
          • GODEBUG=schedtrace=X 每X毫秒打印一次調(diào)度事件。

          GODEBUG 環(huán)境變量可用于禁用標(biāo)準(zhǔn)庫和 runtime 中 instruction set extensions 的使用。

          • GODEBUG=cpu.all=off 禁用所有可選指令集擴(kuò)展的使用。

          • GODEBUG=cpu.extension=off 禁止使用指定指令集擴(kuò)展中的指令。

            extension 是指令集擴(kuò)展名的小寫名稱,例如 sse41 或 avx 。

          參考資料

          [1]

          pprof 可視化工具: https://github.com/google/pprof/blob/master/doc/README.md

          [2]

          profiling data: https://golang.org/pkg/runtime/pprof/

          [3]

          net/http/pprof: https://golang.org/pkg/net/http/pprof/

          [4]

          runtime/pprof: https://golang.org/pkg/runtime/pprof

          [5]

          perf tools: https://perf.wiki.kernel.org/index.php/Tutorial

          [6]

          Instruments: https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/

          [7]

          go tool pprof: https://github.com/google/pprof/blob/master/doc/README.md

          [8]

          callgrind: http://valgrind.org/docs/manual/cl-manual.html

          [9]

          Profiling Go programs: https://blog.golang.org/profiling-go-programs

          [10]

          火焰圖: http://www.brendangregg.com/flamegraphs.html

          [11]

          upstream pprof: https://github.com/google/pprof

          [12]

          pprof.Profile: https://golang.org/pkg/runtime/pprof/#Profile

          [13]

          golang.org/x/net/trace: https://godoc.org/golang.org/x/net/trace

          [14]

          context.Context: https://golang.org/pkg/context#Context

          [15]

          httptrace.ClientTrace: https://golang.org/pkg/net/http/httptrace#ClientTrace

          [16]

          Delve: https://github.com/derekparker/delve

          [17]

          GDB: https://golang.org/doc/gdb

          [18]

          core dump debugging: https://golang.org/wiki/CoreDumpDebugging

          [19]

          go tool trace: https://golang.org/cmd/trace/

          [20]

          GODEBUG: https://golang.org/pkg/runtime/#hdr-Environment_Variables



          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù)?ebook?獲??;還可以回復(fù)「進(jìn)群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。

          瀏覽 118
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色一级大片在线免费看国产 | 91天堂| 加勒比无码综合在线 | 色婷在线视频 | 出租屋女农民工毛片 |