go pprof 性能調優


一.pprof

  • Profiling 是指在程序執行過程中,收集能夠反映程序執行狀態的數據。在軟件工程中,性能分析(performance analysis,也稱為 profiling),是以收集程序運行時信息為手段研究程序行為的分析方法,是一種動態程序分析的方法。
  • GO中自帶兩個庫可以進行程序分析調優:
    1)runtime/pprof 對於本地只跑一次的程序,例如程序中的某一函數調優,調用 pprof 包提供的函數,手動開啟性能數據采集。
    2)net/http/pprof 對於在線服務,對於一個 HTTP Server,訪問 pprof 提供的 HTTP 接口,獲得性能數據。當然,實際上這里底層也是調用的 runtime/pprof 提供的函數,封裝成接口對外提供網絡訪問。
    一般常用net/http/pprof,操作相對簡單
包含的性能數據

  • allocs 和 heap 采樣的信息一致,不過前者是所有對象的內存分配,而 heap 則是活躍對象的內存分配

二.net/http/pprof 使用

1)導包,啟動端口服務

//只需要在你的程序中加入以下幾行代碼
import _ "net/http/pprof"
func maim() {
      go func() {
            http.ListenAndServe("0.0.0.0:8686", nil)
      }()
}

原理

在初始化導包的時候,pprof 包會自動注冊 handler,即我們調試過程中查看的接口:

func init() {
    http.Handle("/debug/pprof/", http.HandlerFunc(Index))
    http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
    http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
    http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
    http.Handle("/debug/pprof/trace", http.HandlerFunc(Trace))
}

2)服務啟動后,可以瀏覽器訪問

http://127.0.0.1:8686/debug/pprof/

由於網頁般數據可讀性較差,服務器終端一般用命令行讀取數據

# 下載 cpu profile,
go tool pprof http://47.93.238.9:8080/debug/pprof/profile

# 默認手機30S的數據,通過seconds調整時間120s
go tool pprof http://47.93.238.9:8080/debug/pprof/profile?seconds=120     

# 下載 heap profile
go tool pprof http://47.93.238.9:8080/debug/pprof/heap

# 下載 goroutine profile
go tool pprof http://47.93.238.9:8080/debug/pprof/goroutine

# 下載 block profile
go tool pprof http://47.93.238.9:8080/debug/pprof/block

# 下載 mutex profile
go tool pprof http://47.93.238.9:8080/debug/pprof/mutex

3)輸入上述命令后,會打開終端交互界面,交互常用命令 top、 list、 traces、 web

- top

獲取前20條,cpu占用的函數
flat--- 該函數占時
flat% --- 該函數相對於總耗時的百分比
sum% --- 前面累計每一行flat 占比
cum --- 該函數以及該函數調用的其他函數總耗時
cum --- 對應的百分比

- list 具體函數: 如結合上圖 list Eat 直接定位到消耗資源的代碼處

- traces 列出函數的調用棧

實戰中,首先通過profile,定位cpu消耗暫時較大的函數,然后通過heap定位內存占用較大的函數邏輯。

通過pprof定位性能瓶頸,根據實際問題優化,從而實現性能的提高

三.內存泄漏查找

內存分配既可以發生在堆上也可以在棧上。堆上分配的內存需要垃圾回收或者手動回收(對於沒有垃圾回收的語言,例如 C++),棧上的內存則通常在函數退出后自動釋放。

什么是內存泄漏

內存泄漏是指程序運行過程中已不再使用的內存,沒有被釋放,導致這些內存一直無法使用,直到程序結束這些內存才被釋放的問題
一般形成主要有兩個原因:

  • goroutine 的阻塞
  • GC回收時,無法實現100%的回收

怎么發現內存泄露

1、監控工具: 固定周期對進程內存占用采樣,數據可視化后,根據內存占用走勢(持續上升)
- 雲平台的監控工具,或者建立一個腳本,定時執行采集數據

2、go pprof 間隔一段時間采集文件,對比分析是否存在明顯的增量
對比heap
1)通過 go tool pprof http://47.93.238.9:8080/debug/pprof/heap 命令,在間隔一段時間后,分別獲取兩個文件;
2)go tool pprof -base file1 file2 對比兩個文件,top獲取對比后占用增加明顯的函數塊
對比goroutine
1)通過 go tool pprof http://47.93.238.9:8080/debug/pprof/goroutine命令,在間隔一段時間后,分別獲取兩個文件;
2)go tool pprof -base file1 file2 對比兩個文件,top獲取對比后占用增加明顯的函數塊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM