gRPC的請求追蹤神器 go tool trace

小魔童哪吒發表於2021-06-01
[TOC]

前言

我們來回顧一下之前分享的知識點:

介紹了基本你的gRPC的使用方式,框架,互動方式等

分享了gRPC的四種認證方式中重要的2種方式,有興趣可以點選看看哦

整理了openssl 證照的生成,關鍵點已經高亮標註,值得一看

gRPC生態中的中介軟體,主要是做統一認證工作,不必要在每一個介面中都寫一次認證方式

文章中有分享gRPC的各種功能的中介軟體,有興趣可以點選連結,大佬們還請不吝賜教

go tool trace

今天我們來介紹一下go的請求追蹤,也就是說go Trace ,分享trace有如下幾個原因:

  • 學習完trace之後,你能夠自己去實踐,清晰的瞭解整個程式的呼叫棧
  • 可以通過追蹤器捕獲大量資訊,如圖

  • 可以更快的解決我們專案中的疑難雜症

我們或許都有這樣的體會,自己思考明白,設計出來的程式,可以很清晰明瞭的將細節解釋明白,對功能的增刪改也是可以做到靈活應對。

可是讓我們一下子去修改別人寫的功能或模組的時候,很多時候會一臉懵逼,這也不敢動,那也不敢動,在不理解的情況下,有疑問,一定要問清楚原理和邏輯,否則搞不好就是線上問題。

如上情況,最重要的一個原因就是自己對當前模組/功能的熟悉程度,以及自己的思維模型是否可遷移。

總而言之,對程式,要有敬畏之心,好奇之心,持之以恆專研下去,要有解決問題的決心。

用go tool trace具體哪些地方合適,哪些地方不合適?

不合適

  • 執行緩慢的函式,或者找到大部分CPU時間花費在哪裡,術業有專攻,看CPU時間花費,是有專門的工具的 go tool pprof

合適

  • 找出程式在一段時間內正在做什麼
  • go tool trace 可以通過 view trace連結提供的其他視覺化功能,對於診斷爭用問題幫助極大

開始寫一個DEMO

GOMAXPROCS設定可以同時執行的cpu的最大數量,此處我們設定為 1

server.go

package main

import (
   "context"
   "fmt"
   "os"
   "runtime"
   "runtime/trace"
   "sync"
)

func main() {
   // 使用 GOMAXPROCS設定可以同時執行的cpu的最大數量 為 1 個
   runtime.GOMAXPROCS(1)

   f, _ := os.Create("myTrace.dat")
   defer f.Close()


   //開始跟蹤,在跟蹤時,跟蹤將被緩衝並寫入 一個我們指定的檔案中
   _ = trace.Start(f)
   defer trace.Stop()

   // 我們們自定義一個任務
   ctx, task := trace.NewTask(context.Background(), "customerTask")
   defer task.End()

   var wg sync.WaitGroup
   wg.Add(10)
   for i := 0; i < 10; i++ {
      // 啟動10個協程,模擬做任務
      go func(num string) {
         defer wg.Done()

         // 標記  num
         trace.WithRegion(ctx, num, func() {
            var sum, i int64
            // 模擬執行任務
            for ; i < 500000000; i++ {
               sum += i
            }
            fmt.Println(num, sum)
         })
      }(fmt.Sprintf("num_%02d", i))
   }
   wg.Wait()
}

操作步驟:

  • 編譯並執行會生成我們既定好的資料檔案
  • 通過go tool trace + myTrace.dat
  • 瀏覽器會彈出traceweb頁面,如下

tag 說明
View trace 檢視視覺化的跟蹤情況
Goroutine analysis 協程分析
Network blocking profile (⬇) 網路擁塞情況
Synchronization blocking profile (⬇) 同步阻塞情況
Syscall blocking profile (⬇) 系統呼叫阻塞情況
Scheduler latency profile (⬇) 排程延遲情況
User-defined tasks 使用者自定義的任務
User-defined regions 使用者自定義的區域
Minimum mutator utilization 最低 Mutator 利用率

View trace

視覺化的web追蹤頁面

tag 說明
時間線 用於顯示執行的時間單元,根據時間維度的不同可以調整區間,可以點選按鈕,便可以在介面上拖拽時間線
用於顯示執行期間的記憶體分配和釋放情況
協程 用於顯示在執行期間的每個 Goroutine 執行階段有多少個協程在執行,其包含 GC 等待(GCWaiting)、可執行(Runnable)、執行中(Running)這三種狀態。
OS 執行緒 顯示在執行期間有多少個執行緒在執行,其包含正在呼叫 SyscallInSyscall)、執行中(Running)這兩種狀態。
虛擬處理器 每個虛擬處理器顯示一行,虛擬處理器的數量一般預設為系統核心數。
協程和事件 顯示在每個虛擬處理器上有什麼 Goroutine 正在執行,而連線行為代表事件關聯。

可以使用 shift + ? 喚出幫助手冊

點選PROC顏色區域

可以看到該處理器此段時間再做什麼事情,如圖

tag 說明
Start 開始時間
Wall Duration: 持續時間
Self Time 執行時間
Start Stack Trace 開始時的堆疊資訊
End Stack Trace 結束時的堆疊資訊
Incoming flow 輸入流
Outgoing flow 輸出流
Preceding events 之前的事件
Following events 之後的事件
All connected 所有連線的事件

Event(s)下方的 Preceding events 點選進去可以看到每一個呼叫棧的執行時間

使用者自定義任務如何檢視?

  • User-defined tasks
  • 點選Count
  • goroutine view
  • 點選顏色區域

即可看到此段時間的呼叫棧,開始時間,結束時間,以及使用者定義的任務開了多少個協程等等

User-defined tasks

點選Count

點選goroutine view

點選顏色區域

即可看到此段時間具體在執行什麼動作,具體的資訊如下

使用者自定義區域如何檢視呢?

與上述檢視使用者自定義任務的方式大同小異,如下

  • User-defined regions
  • 點選具體的Count

User-defined regions

點選具體的Count

即可檢視到此協程的總共耗時,網路擁塞,同步阻塞,系統呼叫阻塞,排程等待,垃圾回收掃描,垃圾回收暫停的相關引數資訊

那麼某一些關鍵的goroutine被阻止執行時,可能會有延遲問題,大概的原因相信大家應該有些譜了吧

  • 系統呼叫時被阻塞;
  • 被共享記憶體阻塞(通道/互斥等)
  • 排程程式沒有按照我們所期望的頻率執行協程
  • 被runtime系統(例如GC)阻塞

正好上述原因的追蹤都可以使用go tool trace 識別到 ,對於我們追蹤問題,查詢問題原理起了很好的助力作用

好了,本次就到這裡,下一次分享 gRPC的HTTP閘道器

技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。

我是小魔童哪吒,歡迎點贊關注收藏,下次見~

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章