前言
这是一篇给网友的文章,正好最近在研究分析golang的性能,我觉得是时候来一个了断了。
正文
1.一句话简介
Golang自带的一款开箱即用的性能监控和分析工具。
(全篇看的过程中没必要特意记忆、看完自然让你有不一样的感觉)
2.使用姿势?
2.1 runtime/pprof
手动调用runtime.StartCPUProfile/runtime.StopCPUProfile等API来进行数据的采集。
优点:灵活性高、按需采集。
使用场景:工具型应用(比如说定制化的分析小工具、集成到公司监控系统)
2.2 net/http/pprof
通过http服务来获取Profile采样文件。 import _ "net/http/pprof"
优点:简单易用。
使用场景:在线服务(一直运行着的程序)
(net/http/pprof中只是使用runtime/pprof包来进行封装了一下,并在http端口上暴露出来)
2.3 go test
通过命令go test -bench . -cpuprofile cpu.prof
来进行采集数据。
优点:针对性强、细化到函数
使用场景:进行某函数的性能测试
3 分析姿势?
3.1 数据采集
分析的基础是得到相应的采集文件。runtime/pprof 和 go test 这两个均为命令行采集得到(下文以分析cpu的进行举例))。而net/http/pprof通过接口的方式将数据突出。
1.go test的方式很简单,命令:go test -bench . -cpuprofile cpu.prof
就可以生成。
2.runtime/pprof,直接上一个最简单的代码。
package main
import (
"fmt"
"os"
"runtime/pprof"
"time"
)
// 一段有问题的代码
func do() {
var c chan int
for {
select {
case v := <-c:
fmt.Printf("我是有问题的那一行,因为收不到值:%v", v)
default:
}
}
}
func main() {
// 创建分析文件
file, err := os.Create("./cpu.prof")
if err != nil {
fmt.Printf("创建采集文件失败, err:%v\n", err)
return
}
// 进行cpu数据的获取
pprof.StartCPUProfile(file)
defer pprof.StopCPUProfile()
// 执行一段有问题的代码
for i := 0; i < 4; i++ {
go do()
}
time.Sleep(10 * time.Second)
}
执行命令:
go run pprof.go
然后会得到数据采集文件:cpu.prof。(这个文件后文会用到)
3.http的方式,上代码:
package main
import (
"fmt"
"net/http"
_ "net/http/pprof" // 第一步~
)
// 一段有问题的代码
func do() {
var c chan int
for {
select {
case v := <-c:
fmt.Printf("我是有问题的那一行,因为收不到值:%v", v)
default:
}
}
}
func main() {
// 执行一段有问题的代码
for i := 0; i < 4; i++ {
go do()
}
http.ListenAndServe("0.0.0.0:6061", nil)
}
通过代码中的关键两步,执行起来就可以通过 http://127.0.0.1:6061/debug/pprof/
看到对应的数据啦~
3.2 数据内容
不管是前文哪种方式获取,都可以进行分析。这里http的方式把可以看到的信息全部都列出来了。
类型 | 描述 |
---|---|
allocs | 内存分配情况的采样信息 |
blocks | 阻塞操作情况的采样信息 |
cmdline | 显示程序启动命令参数及其参数 |
goroutine | 显示当前所有协程的堆栈信息 |
heap | 堆 |