pprof在http服务的使用

使用前准备

编译运行:

$ go build -o pprof_http pprof_http.go
$ ./pprof_http

模拟请求:

$ wrk -c 400 -t 8 -d 3m http://localhost:9876/test

CPU 的占用分析使用

打开 http://localhost:9876/debug/pprof:

../../../_images/pprof_http2.png
$ wget http://localhost:9876/debug/pprof/profile
$ go tool pprof pprof_http profile
(pprof) top 5
Showing nodes accounting for 4.93mins, 97.46% of 5.06mins total
Dropped 180 nodes (cum <= 0.03mins)
Showing top 5 nodes out of 42
      flat  flat%   sum%        cum   cum%
  4.64mins 91.69% 91.69%   4.64mins 91.69%  main.doSomeThingOne
  0.11mins  2.16% 93.85%   0.11mins  2.16%  runtime.usleep
  0.09mins  1.83% 95.68%   0.09mins  1.84%  runtime.newstack
  0.08mins  1.52% 97.19%   0.08mins  1.52%  runtime.pthread_cond_signal
  0.01mins  0.27% 97.46%   0.14mins  2.68%  math/rand.(*Rand).Int31n
(pprof) web   // 打开本篇最后的效果图

内存快照的占用分析

$ wget http://localhost:9876/debug/pprof/heap
$ go tool pprof pprof_http heap
(pprof)

源码

package main

import (
  "bytes"
  "io/ioutil"
  "log"
  "math/rand"
  "net/http"

  _ "net/http/pprof"
)

func main() {
  http.HandleFunc("/test", handler)
  log.Fatal(http.ListenAndServe(":9876", nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
  err := r.ParseForm()
  if nil != err {
    w.Write([]byte(err.Error()))
    return
  }
  doSomeThingOne(10000)
  buff := genSomeBytes()
  b, err := ioutil.ReadAll(buff)
  if nil != err {
    w.Write([]byte(err.Error()))
    return
  }
  w.Write(b)
}

func doSomeThingOne(times int) {
  for i := 0; i < times; i++ {
    for j := 0; j < times; j++ {

    }
  }
}

func genSomeBytes() *bytes.Buffer {
  var buff bytes.Buffer
  for i := 1; i < 20000; i++ {
    buff.Write([]byte{'0' + byte(rand.Intn(10))})
  }
  return &buff
}

效果图

../../../_images/pprof_http.svg