前言
相比于 C++ 在 pod 中做 profiling, 那么对于云原生的 golang 来说就太方便了。下面我将讲述下我做 golang profiling 的具体过程和步骤。由于我们是基于 Restful 接口的系统设计,所以以下 profiling 都是基于 http/pprof 做的分析。
操作步骤
在代码中添加 handlers
例如:
// This is a function creating a HTTP2 server. and only registered profile and heap path,
// for others profiling path, you can add it according to yourself.
func profiling() {
mux := http.NewServeMux()
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
mux.HandleFunc("/debug/memstat", func(w http.ResponseWriter, r *http.Request) {
var m runtime.MemStats
runtime.ReadMemStats(&m)
//fmt.Println(m)
fmt.Printf("HeapSys %d, HeapAlloc %d, HeapIdle %d, HeapReleased%d,\n", m.HeapSys, m.HeapAlloc,
m.HeapIdle, m.HeapReleased)
//result := fmt.Sprintf("%v", m)
w.WriteHeader(http.StatusOK)
//w.Write([]byte(result))
})
h2s := &http2.Server{}
httpServer := &http.Server{
Addr: ":10000",
Handler: h2c.NewHandler(mux, h2s),
}
if err := httpServer.ListenAndServe(); err != nil {
golog.Message(golog.Error, "Error while listening")
}
}
// then in the main function, you can invoke it.
go profiling()
编译代码并更新到 pod 中
编译代码,重新创建 image,并更新到 deployment 里面。这里根据自己的环境进行部署。
暴露 pod 中的 server 的端口
// you can use kubectl port-forward --help to view detailed useage.
kubectl port-forward pods/yourpod port:port
NOTE: 这里需要注意一点,就是如果是添加的新的端口,需要在 deployment 中的 container.ports 下面加上。
load 测试
这里我用的是 h2load.
h2load -D 2 -c 10 -m 10 -H':method:POST' -H'content-type:application/json' your_restful_uri -d data.txt
Profiling 分析
你需要用 pprof 命令采集 sample, 然后对采集到的信息进行分析。
// more detailed command usage you can refer to https://golang.org/pkg/net/http/pprof/
go tool pprof http://localhost:9001/debug/pprof/profile
go tool pprof -alloc_objects http://localhost:9001/debug/pprof/heap
go tool pprof http://localhost:9001/debug/pprof/heap
如何进行分析,可以参考 diagnostics, 如果你不能打开官方文档,可以参考 performance optimization, 里面讲述了详细的 profiling 的使用。
火焰图分析
-
安装 go-torch
go get github.com/uber/go-torch
-
安装 FlameGraph
cd $WORK_PATH && git clone https://github.com/brendangregg/FlameGraph.git export PATH=$PATH:$WORK_PATH/FlameGraph
-
安装 graphviz
sudo apt-get install graphviz(ubuntu) or yum install graphviz(CentOS, Redhat)
-
使用
go-torch -u http://localhost:8888/debug/pprof/ -p > profile-local.svg
然后浏览器打开生成的文件 profile-local.svg.