前言
我們來回顧一下之前分享的知識點:
介紹了基本你的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
- 瀏覽器會彈出
trace
的web頁面
,如下
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 執行緒 | 顯示在執行期間有多少個執行緒在執行,其包含正在呼叫 Syscall (InSyscall )、執行中(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 協議》,轉載必須註明作者和本文連結