推薦一款不錯的 Go 持續分析工具

年前土撥鼠分享了一篇鳥窩老師寫的 Pyroscope: 簡單易用的持續分析 (Continuous profiling) 服務器。今天土撥鼠帶來一篇官方更生動的實例文章。本篇文章翻譯自 Continuous Profiling for Go Applications[1]。翻譯不當之處煩請指出。

源碼地址:https://github.com/pyroscope-io/pyroscope/tree/main/examples/golang-push。

使用 Pyroscope — 一個開源的持續分析平臺

使用 Pyroscope 分析 Golang Rideshare 應用程序

在這個例子中,展示了一個基本的用例,即如何使用 Pyroscope[2](一個開源的分析庫)來加速 Golang 應用程序使用持續分析。

我們模擬了一家 "拼車" 公司,該公司在 main.go 中有三個路徑endpoint(這裏 endpoint 翻譯參考 阮一峯 [3] 寫的 RESTful API 設計指南 [4] 中的翻譯):

我還模擬在 3 個不同的區域運行 3 個不同的服務器(通過 docker-compose.yml[5])

Pyroscope 最有用的功能之一是能夠以對你有意義的方式標記數據。在本例中,我們有兩個自然劃分,因此我們 "標記" 我們的數據來表示它們:

對區域進行靜態標記

標記靜態內容(如region)可以在 main() 函數的初始化代碼中完成:

 pyroscope.Start(pyroscope.Config{
  ApplicationName: "ride-sharing-app",
  ServerAddress:   serverAddress,
  Logger:          pyroscope.StandardLogger,
  Tags:            map[string]string{"region": os.Getenv("REGION")},
 })

在函數內進行動態標記

像我們爲車輛vehicle標記的那樣,可以在我們的實用函數FindNearestVehicle()中使用pyroscope.TagWrapper() 來動態地標記一些東西。

func FindNearestVehicle(search_radius int64, vehicle string) {
  
 pyroscope.TagWrapper(context.Background(), pyroscope.Labels("vehicle", vehicle), func(ctx context.Context) {
     
        // 模擬找到一輛車 Mock "doing work" to find a vehicle 
        var i int64 = 0
        start_time := time.Now().Unix()
        for (time.Now().Unix() - start_time) < search_radius {
             i++
        }
     })
}

這塊的功能是:

  1. 它添加了標籤pyroscope.Labels("vehicle", vehicle)

  2. 它執行 FindNearestVehicle() 函數

  3. 在塊結束之前,它(在幕後)從應用程序中移除了pyroscope.Labels("vehicle", vehicle),因爲該塊已經執行完成。

使用火焰圖顯示性能瓶頸

在分析應用程序的配置文件輸出時,第一步是注意最大的節點,即應用程序消耗最多資源的地方。在本例中,它恰好是 OrderCar() 函數。

使用 Pyroscope 包的好處是,現在我們可以進一步研究爲什麼OrderCar()函數會有問題。標記regionvehicle使我們可以對兩個很好的假設進行測試:

要對此進行分析,我們可以從 "Select Tag" 下拉列表中選擇一個或多個標籤:

使用標籤縮小性能問題的範圍

知道 OrderCar() 函數存在問題後,我們會自動選擇該標籤。然後,在檢查多個region標籤後,通過查看時間線可以清楚地看出 us-west-1 區域存在問題,它在高 CPU 時間和低 CPU 時間之間交替。

我們還可以看到,mutexLock() 函數消耗了近 70% 的 CPU 資源。

比較兩個時間段

使用 Pyroscope 的 "比較視圖 - comparison view",我們可以從時間軸中選擇兩個不同的時間範圍來比較生成的火焰圖。左側時間軸上的粉紅色部分生成左側火焰圖,右側的藍色部分表示右側火焰圖。

當我們選擇低 CPU 使用率週期和高 CPU 使用率週期時,我們可以看到 mutexLock() 函數中存在不同的行爲 ,其中它在低 CPU 時間佔用 33% 的 CPU,在高 CPU 時間佔用 71% 的 CPU。

可視化兩個火焰圖之間約有 112% 的性能差異

雖然在這種情況下,差異是很顯而易見的,但有時兩個火焰圖之間的差異最好通過相互疊加才能更好地可視化。無需更改任何參數,我們只需選擇 **(Diff View) 差異視圖選項卡 **,即可查看顏色編碼的差異火焰圖中表示的差異。

更多用例

無論你是從事副業的開發人員,還是一個想知道 "如何加快我的 Go 應用程序" 的 DevOps 工程師,Pyroscope 都有許多用例,可以輕鬆瞭解如何分析您的應用程序。下面是一些示例:

未來路線圖

如果你想嘗試此示例,並查看如何將其調整到您的 Go 應用程序,請單擊 github 上此示例 [6] 的鏈接。持續分析已成爲監視和調試性能問題(可以說是可觀察性的第四個支柱)的日益流行的工具。

如果您對 Pyroscope[7] 如何改進有想法,請隨時在 GitHub 頁面上提交你的問題!感謝您的閱讀。

參考資料

[1]

Continuous Profiling for Go Applications: https://betterprogramming.pub/continuous-profiling-go-applications-8cdbdfdfc5ab

[2]

Pyroscope: https://github.com/pyroscope-io/pyroscope

[3]

阮一峯: https://www.ruanyifeng.com/

[4]

RESTful API 設計指南: https://www.ruanyifeng.com/blog/2014/05/restful_api.html

[5]

docker-compose.yml: https://github.com/pyroscope-io/pyroscope/blob/main/examples/golang-push/rideshare/docker-compose.yml

[6]

github 上此示例: https://github.com/pyroscope-io/pyroscope/blob/main/examples/golang-push/README.md

[7]

Pyroscope: https://pyroscope.io/

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/GrDFbTjXvC_uyXynceOpzw