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

淺談Pprof,你了解多少?

開發(fā) 開發(fā)工具
對于大多數(shù) Gopher 而言,一般平時最主要的工作內(nèi)容除了實現(xiàn)各種無聊的業(yè)務(wù)邏輯之外,剩下的就是解決各種瑣碎的問題。

[[403923]]

本文轉(zhuǎn)載自微信公眾號「架構(gòu)技術(shù)漫談」,作者LA0WAN9。轉(zhuǎn)載本文請聯(lián)系架構(gòu)技術(shù)漫談公眾號。

對于大多數(shù) Gopher 而言,一般平時最主要的工作內(nèi)容除了實現(xiàn)各種無聊的業(yè)務(wù)邏輯之外,剩下的就是解決各種瑣碎的問題。比如:查詢性能瓶頸在哪里?查詢內(nèi)存泄漏在哪里?好在 pprof 是處理此類問題的利器,共有兩套標(biāo)準(zhǔn)庫,分別適用于不同的場景:

  • runtime/pprof[1]:采集工具型應(yīng)用運行數(shù)據(jù)進行分析
  • net/http/pprof[2]:采集服務(wù)型應(yīng)用運行時數(shù)據(jù)進行分析

命令行工具「go test」就包含了 runtime/pprof,相關(guān)參數(shù)請參考「go help testflag」:

  1. shell> go test -cpuprofile cpu.out -memprofile mem.out -bench . 

不過和 runtime/pprof 相比,更常用的是 net/http/pprof,接下來我們主要通過它來解決一些常見問題,想要激活 net/http/pprof 的話很簡單,只要導(dǎo)入對應(yīng)的包并啟動服務(wù)即可:

  1. import _ "net/http/pprof" 
  2.  
  3. func main() { 
  4.  _ = http.ListenAndServe("localhost:6060", nil) 

需要注意的是,千萬別讓外網(wǎng)訪問到 pprof,否則可能會導(dǎo)致出現(xiàn)安全問題。有興趣的讀者可以嘗試通過 google 搜索「intitle:/debug/pprof/ inurl:/debug/pprof/」看看反面例子。

Profile

pprof 預(yù)置了很多種不同類型的 profile,我們可以按照自己的需要選擇:

  • allocs:A sampling of all past memory allocations
  • block:Stack traces that led to blocking on synchronization primitives
  • goroutine:Stack traces of all current goroutines
  • heap:A sampling of memory allocations of live objects
  • mutex:Stack traces of holders of contended mutexes
  • profile:CPU profile
  • threadcreate:Stack traces that led to the creation of new OS threads

其中最常用的是 profile 和 heap,分別用來診斷 CPU 和內(nèi)存問題。

CPU profiling

演示代碼模擬了 CPU 密集型任務(wù)(onCPU)和耗時的網(wǎng)絡(luò)請求(offCPU):

  1. package main 
  2.  
  3. import ( 
  4.  "log" 
  5.  "net/http" 
  6.  _ "net/http/pprof" 
  7.  "runtime" 
  8.  "time" 
  9.  
  10.  "github.com/felixge/fgprof" 
  11.  
  12. const cpuTime = 1000 * time.Millisecond 
  13.  
  14. func main() { 
  15.  runtime.SetBlockProfileRate(1) 
  16.  runtime.SetMutexProfileFraction(1) 
  17.  
  18.  go func() { 
  19.   http.Handle("/debug/fgprof", fgprof.Handler()) 
  20.   log.Println(http.ListenAndServe(":6060", nil)) 
  21.  }() 
  22.  
  23.  for { 
  24.   cpuIntensiveTask() 
  25.   slowNetworkRequest() 
  26.  } 
  27.  
  28. func cpuIntensiveTask() { 
  29.  start := time.Now() 
  30.  
  31.  for time.Since(start) <= cpuTime { 
  32.   for i := 0; i < 1000; i++ { 
  33.    _ = i 
  34.   } 
  35.  } 
  36.  
  37. func slowNetworkRequest() { 
  38.  resp, err := http.Get("http://httpbin.org/delay/1"
  39.  
  40.  if err != nil { 
  41.   log.Fatal(err) 
  42.  } 
  43.  
  44.  defer resp.Body.Close() 

通過 go tool pprof 查看 /debug/pprof/profile:

  1. go tool pprof -http :8080 http://localhost:6060/debug/pprof/profile 

結(jié)果發(fā)現(xiàn) profile 只能檢測到 onCPU(也就是 cpuIntensiveTask)部分,卻不能檢測到 offCPU (也就是 slowNetworkRequest)部分:

profile

為了檢測 offCPU 部分,我們引入 fgprof,通過 go tool pprof 查看 /debug/fgprof:

  1. go tool pprof -http :8080 http://localhost:6060/debug/fgprof 

結(jié)果發(fā)現(xiàn) fgprof 不僅能檢測到 onCPU(也就是 cpuIntensiveTask)部分,還能檢測到 offCPU (也就是 slowNetworkRequest)部分:

fgprof

實際應(yīng)用中,最好對你的瓶頸是 onCPU 還是 offCPU 有一個大體的認(rèn)識,進而選擇合適的工具,如果不確定就直接用 fgprof,不過需要注意的是 fgprof 對性能的影響較大。

Memory profiling

演示代碼模擬了一段有內(nèi)存泄漏問題的程序:

  1. package main 
  2.  
  3. import ( 
  4.  "log" 
  5.  "net/http" 
  6.  _ "net/http/pprof" 
  7.  "time" 
  8.  
  9. func main() { 
  10.  go func() { 
  11.   log.Println(http.ListenAndServe(":6060", nil)) 
  12.  }() 
  13.  
  14.  for { 
  15.   leak() 
  16.  } 
  17.  
  18. func leak() { 
  19.  s := make([]string, 10) 
  20.  
  21.  for i := 0; i < 10000000; i++ { 
  22.   s = append(s, "leak"
  23.  
  24.   if (i % 10000) == 0 { 
  25.    time.Sleep(1 * time.Second
  26.   } 
  27.  
  28.   _ = s 
  29.  } 

通過 go tool pprof 查看 /debug/pprof/head(這次不用 web,用命令行):

heap

通過 top 命令可以很直觀的看出哪里可能出現(xiàn)了內(nèi)存泄漏問題。不過這里有一個需要說明的問題是內(nèi)存占用大的地方本身可能是正常的,與內(nèi)存的絕對值大小相比,我們更應(yīng)該關(guān)注的是不同時間點內(nèi)存相對變化大小,這里可以使用參數(shù) base 或者 diff_base:

heap

本文篇幅有限,無法列舉更多的例子,有興趣的讀者推薦參考「golang pprof 實戰(zhàn)[3]」。

參考資料

[1]runtime/pprof: https://golang.org/pkg/runtime/pprof/

[2]net/http/pprof: https://golang.org/pkg/net/http/pprof/

[3]golang pprof 實戰(zhàn): https://blog.wolfogre.com/posts/go-ppof-practice/

 

責(zé)任編輯:武曉燕 來源: 架構(gòu)技術(shù)漫談
相關(guān)推薦

2020-03-25 08:47:22

智能邊緣邊緣計算網(wǎng)絡(luò)

2012-12-27 10:58:24

KVMKVM概念

2023-10-25 08:17:06

Lite模式代理類

2023-10-29 08:35:47

AndroidAOP編程

2022-06-07 07:37:40

線程進程開發(fā)

2019-08-07 17:18:18

云計算云原生函數(shù)

2022-02-08 12:06:12

云計算

2023-09-07 10:26:50

接口測試自動化測試

2025-01-16 10:41:40

2011-08-23 11:03:35

ATM

2023-08-17 10:12:04

前端整潔架構(gòu)

2021-12-09 07:47:58

Flink 提交模式

2015-11-09 10:44:37

DevOpsIT運維

2020-12-10 09:00:00

開發(fā).NET工具

2023-12-24 12:56:36

協(xié)程

2018-10-15 12:42:21

2017-05-26 18:30:34

華為

2023-09-14 08:30:46

JsonPathXPath

2018-04-25 15:53:12

霧計算

2021-09-07 18:34:14

混合云架構(gòu)私有云云計算
點贊
收藏

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