pprof在30秒采样时间窗口内对CPU耗时以函数为单位进行分类汇总,按函数调用关系来组织,一个函数就是一个节点,从根节点开始逐步分解CPU耗时,如果有多条独立的函数调用trace就会有多个根节点。下面这个例子是一个典型的HTTP服务,有2条函数调用trace,一个是对HTTP请求的响应,另一个是计时器定时触发。需要注意的是,等待的时间(如time.Sleep)的CPU耗时是0。
调用关系:
- httpServe
- handler1 > func1_1 (Sleep 1秒) > func1_2
- handler2 > func1_2
- timedTask
pprof.go
package main
import (
"fmt"
"net/http"
_ "net/http/pprof"
"time"
)
var container []byte
func func1_2() {
container = make([]byte, 100*1024*1024)
for i := 0; i < 100*1024*1024; i++ {
container[i] = 0
}
}
func func1_1() {
time.Sleep(1 * time.Second)
func1_2()
}
func func2() {
container = make([]byte, 100*1024*1024)
for i := 0; i < 100*1024*1024; i++ {
container[i] = 0
}
}
func handler1(w http.ResponseWriter, r *http.Request) {
func1_1()
}
func handler2(w http.ResponseWriter, r *http.Request) {
func2()
}
func timedTask() {
ticker := time.NewTicker(time.Second)
for {
select {
case t := <-ticker.C:
container = make([]byte, 100*1024*1024)
for i := 0; i < 100*1024*1024; i++ {
container[i] = 0
}
fmt.Println("Current time: ", t)
}
}
}
func main() {
go timedTask()
http.HandleFunc("/test1", handler1)
http.HandleFunc("/test2", handler2)
http.ListenAndServe(":8888", nil)
}
运行go run pprof.go
生成CPU框图,下面这条命令需要30秒的采样时间,在采样期间各请求/test1和/test2各3次。
go tool pprof -png http://127.0.0.1:8888/debug/pprof/profile > cpu.png
cpu.png
相关文章: