自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go 工程師必學(xué):Go 大殺器之跟蹤剖析 Trace

開發(fā) 后端
在剛開始查看問題時,除非是很明顯的現(xiàn)象,否則不應(yīng)該一開始就陷入細節(jié)。因此我們一般先查看 “Scheduler latency profile”,我們能通過 Graph 看到整體的調(diào)用開銷情況。

 [[398395]]

本文轉(zhuǎn)載自微信公眾號「腦子進煎魚了」,作者陳煎魚。轉(zhuǎn)載本文請聯(lián)系腦子進煎魚了公眾號。

大家好,我是煎魚。

前段時間分享了《Go 程序崩了?煎魚教你用 PProf 工具來救火!》,但有時候單單使用 pprof 還不一定足夠完整觀查并解決問題,因為在真實的程序中還包含許多的隱藏動作,例如:

  • Goroutine 在執(zhí)行時會做哪些操作?
  • Goroutine 執(zhí)行/阻塞了多長時間?
  • Syscall 在什么時候被阻止?在哪里被阻止的?
  • 誰又鎖/解鎖了 Goroutine ?
  • GC 是怎么影響到 Goroutine 的執(zhí)行的?

這些東西用 pprof 是很難分析出來的,但如果你又想知道上述的答案的話,你可以用本章節(jié)的主角 go tool trace 來打開新世界的大門。

一起愉快地開始吸魚之路。

初步了解

  1. import ( 
  2.  "os" 
  3.  "runtime/trace" 
  4.  
  5. func main() { 
  6.  trace.Start(os.Stderr) 
  7.  defer trace.Stop() 
  8.  
  9.  ch := make(chan string) 
  10.  go func() { 
  11.   ch <- "Go語言編程之旅" 
  12.  }() 
  13.  
  14.  <-ch 

生成跟蹤文件:

  1. $ go run main.go 2> trace.out 

啟動可視化界面:

  1. $ go tool trace trace.out 
  2. 2019/06/22 16:14:52 Parsing trace... 
  3. 2019/06/22 16:14:52 Splitting trace... 
  4. 2019/06/22 16:14:52 Opening browser. Trace viewer is listening on http://127.0.0.1:57321 

查看可視化界面:

View trace:查看跟蹤

Goroutine analysis:Goroutine 分析

Network blocking profile:網(wǎng)絡(luò)阻塞概況

Synchronization blocking profile:同步阻塞概況

Syscall blocking profile:系統(tǒng)調(diào)用阻塞概況

Scheduler latency profile:調(diào)度延遲概況

User defined tasks:用戶自定義任務(wù)

User defined regions:用戶自定義區(qū)域

Minimum mutator utilization:最低 Mutator 利用率

調(diào)度延遲概況

在剛開始查看問題時,除非是很明顯的現(xiàn)象,否則不應(yīng)該一開始就陷入細節(jié)。

因此我們一般先查看 “Scheduler latency profile”,我們能通過 Graph 看到整體的調(diào)用開銷情況,如下:

演示程序比較簡單,因此這里就兩塊,一個是 trace 本身,另外一個是 channel 的收發(fā)。

Goroutine 分析

第二步看 “Goroutine analysis”,我們能通過這個功能看到整個運行過程中,每個函數(shù)塊有多少個有 Goroutine 在跑。

觀察每個的 Goroutine 的運行開銷都花費在哪個階段。如下:

通過上圖我們可以看到共有 3 個 goroutine,分別是:

  1. runtime.main。 
  2.  
  3. runtime/trace.Start.func1。 
  4.  
  5. main.main.func1。 

它們都做了些什么事呢,我們可以通過點擊具體細項去觀察。如下:

同時也可以看到當(dāng)前 Goroutine 在整個調(diào)用耗時中的占比,以及 GC 清掃和 GC 暫停等待的一些開銷。

如果你覺得還不夠,可以把圖表下載下來分析,相當(dāng)于把整個 Goroutine 運行時掰開來看了,這塊能夠很好的幫助我們對 Goroutine 運行階段做一個的剖析,可以得知到底慢哪,然后再決定下一步的排查方向。

如下:

名稱 含義 耗時
Execution Time 執(zhí)行時間 3140ns
Network Wait Time 網(wǎng)絡(luò)等待時間 0ns
Sync Block Time 同步阻塞時間 0ns
Blocking Syscall Time 調(diào)用阻塞時間 0ns
Scheduler Wait Time 調(diào)度等待時間 14ns
GC Sweeping GC 清掃 0ns
GC Pause GC 暫停 0ns

查看跟蹤

在對當(dāng)前程序的 Goroutine 運行分布有了初步了解后,我們再通過 “查看跟蹤” 看看之間的關(guān)聯(lián)性,如下:

這個跟蹤圖粗略一看,相信有的小伙伴會比較懵逼,我們可以依據(jù)注解一塊塊查看,如下:

  • 時間線:顯示執(zhí)行的時間單元,根據(jù)時間維度的不同可以調(diào)整區(qū)間,具體可執(zhí)行 shift + ? 查看幫助手冊。
  • 堆:顯示執(zhí)行期間的內(nèi)存分配和釋放情況。
  • 協(xié)程:顯示在執(zhí)行期間的每個 Goroutine 運行階段有多少個協(xié)程在運行,其包含 GC 等待(GCWaiting)、可運行(Runnable)、運行中(Running)這三種狀態(tài)。
  • OS 線程:顯示在執(zhí)行期間有多少個線程在運行,其包含正在調(diào)用 Syscall(InSyscall)、運行中(Running)這兩種狀態(tài)。
  • 虛擬處理器:每個虛擬處理器顯示一行,虛擬處理器的數(shù)量一般默認(rèn)為系統(tǒng)內(nèi)核數(shù)。
  • 協(xié)程和事件:顯示在每個虛擬處理器上有什么 Goroutine 正在運行,而連線行為代表事件關(guān)聯(lián)。

點擊具體的 Goroutine 行為后可以看到其相關(guān)聯(lián)的詳細信息,這塊很簡單,大家實際操作一下就懂了。文字解釋如下:

  • Start:開始時間
  • Wall Duration:持續(xù)時間
  • Self Time:執(zhí)行時間
  • Start Stack Trace:開始時的堆棧信息
  • End Stack Trace:結(jié)束時的堆棧信息
  • Incoming flow:輸入流
  • Outgoing flow:輸出流
  • Preceding events:之前的事件
  • Following events:之后的事件
  • All connected:所有連接的事件

查看事件

我們可以通過點擊 View Options-Flow events、Following events 等方式,查看我們應(yīng)用運行中的事件流情況。如下:

通過分析圖上的事件流,我們可得知:

這程序從 G1 runtime.main 開始運行。

在運行時創(chuàng)建了 2 個 Goroutine:

  • 先是創(chuàng)建 G18 runtime/trace.Start.func1。
  • 再是創(chuàng)建 G19 main.main.func1。

同時我們可以通過其 Goroutine Name 去了解它的調(diào)用類型。如下:

runtime/trace.Start.func1 就是程序中在 main.main 調(diào)用了 runtime/trace.Start 方法。

緊接著該方法又利用協(xié)程創(chuàng)建了一個閉包 func1 去進行調(diào)用。

在這里我們結(jié)合開頭的代碼去看的話,很明顯就是 ch 的輸入輸出的過程了。

實戰(zhàn)演練

凌晨三點,突然生產(chǎn)環(huán)境突然出現(xiàn)了問題,機智的你早已埋好 _ "net/http/pprof" 這個神奇的工具。

被告警電話叫醒的你,迷迷糊糊地通過特定的方式執(zhí)行了如下命令:

  1. $ curl http://127.0.0.1:6060/debug/pprof/trace\?seconds\=20 > trace.out 
  2. $ go tool trace trace.out 

查看跟蹤

你很快的看到了熟悉的 List 界面,然后不信邪點開了 View trace 界面,如下:

完全看懵的你,穩(wěn)住,對著合適的區(qū)域執(zhí)行快捷鍵 W 不斷地放大時間線,如下:

經(jīng)過初步排查,你發(fā)現(xiàn)上述絕大部分的 G 竟然都和 google.golang.org/grpc.(*Server).Serve.func 有關(guān),關(guān)聯(lián)的一大串也是 Serve 所觸發(fā)的相關(guān)動作。

這時候有經(jīng)驗的你心里已經(jīng)有了初步結(jié)論,你可以繼續(xù)追蹤 View trace 深入進去。

不過建議先鳥瞰全貌,因此我們再往下看 “Network blocking profile” 和 “Syscall blocking profile” 所提供的信息。

網(wǎng)絡(luò)阻塞概況

系統(tǒng)調(diào)用阻塞概況

通過對以上三項的跟蹤分析,加上這個泄露,這個阻塞的耗時,這個涉及的內(nèi)部方法名,很明顯就是哪位又忘記關(guān)閉客戶端連接了。

這時候我們就可以接下進行下一步的排查和修改了。

總結(jié)

通過本文我們習(xí)得了 go tool trace 的武林秘籍,它能夠跟蹤捕獲各種執(zhí)行中的事件,例如:

  • Goroutine 的創(chuàng)建/阻塞/解除阻塞。
  • Syscall 的進入/退出/阻止,GC 事件。
  • Heap 的大小改變。
  • Processor 啟動/停止等等。

希望你能夠用好 Go 的兩大殺器 pprof + trace 組合,此乃排查好搭檔,誰用誰清楚,即使他并不是絕對的萬能。

 

責(zé)任編輯:武曉燕 來源: 腦子進煎魚了
相關(guān)推薦

2015-08-11 13:00:03

android面試教程

2019-11-18 09:56:48

谷歌Go語言開發(fā)者

2021-10-10 15:01:09

Go 源碼Github

2012-08-06 08:50:05

Go語言

2021-07-12 10:24:36

Go裝飾器代碼

2021-06-10 09:00:32

Go底層代碼

2009-03-11 19:53:26

Linux系統(tǒng)工程師系統(tǒng)管理命令

2019-02-25 22:57:22

數(shù)據(jù)工程師數(shù)據(jù)科學(xué)機器學(xué)習(xí)

2021-05-13 18:53:34

Go編譯器Uber

2017-05-08 11:37:41

Go調(diào)度器源碼分析程序

2024-09-10 09:31:07

開源項目Arthas

2022-03-31 12:08:26

數(shù)據(jù)管理架構(gòu)

2021-06-07 10:47:02

GoGoexit函數(shù)

2020-01-23 15:49:42

區(qū)塊鏈技術(shù)智能

2013-07-24 10:11:50

軟件工程師

2023-07-27 07:37:48

2013-04-18 10:01:01

Fiddler前端

2021-10-12 18:32:17

Go框架測試

2021-12-27 08:27:18

RepoGo 代碼

2021-02-05 18:22:51

GoC剖析
點贊
收藏

51CTO技術(shù)棧公眾號