性能调优原则
- 要依靠数据不要进行猜测
- 要定位最大瓶颈而不是细枝末节
- 不要过早优化
- 不要过度优化
性能分析工具:pprof
pprof是用于可视化和分析性能、分析数据的工具,能告诉我们,应用在什么地方耗费了多少CPU和内存资源。
pprof排查实战
搭建pprof实践项目
通过git工具将项目clone到本地
git clone git@github.com:wolfogre/go-pprof-practice.git
运行该项目并登入:http://localhost:6060/debug/pprof/ 即可进入实践项目
如果输入以上网址打不开,可能是端口被占用了,可以在项目main.go文件下指定服务器地址:
if err := http.ListenAndServe("localhost:6060", nil); err != nil {
log.Fatal(err)
}
CPU排查
在运行pprof项目后,可以在终端输入
go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"
来记录未来10s内CPU性能状态。
命令:top
在这之后在控制台中输入top来查看函数消耗CPU情况。
其中:
- flat: 当前函数本身的执行耗时
- flat%:flat占CPU总时间的比例
- sum%:本行和上面每一行的flat%总和
- cum:指当前函数的本体加上其他调用函数的总消耗
- cum% cum占CPU总时间的比例
由上图可知函数tiger.(*Tiger).Eat 消耗了绝大部分CPU性能。
当flat==cum时,代表该函数没有调用其他函数,CPU消耗全部由自己提供。当flat = 0,代表该函数中只有其他函数的调用
命令:list
知道了问题函数在哪,就可以对其进一步排查,输入指令:list Eat
可以很明显看到第24行中的for循环资源占用最大
Heap-堆内存分析
运行项目后在终端输入:
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"
如果输入上述命令没有弹出该页面,可能是因为没有安装graphviz。官网地址:graphviz.gitlab.io/download/ 注:安装后需要将它的bin文件夹加入到系统环境变量中。
上图中可以看到mouse.(*Mouse).Live函数所占的内存过高
goroutine-协程分析
保持测试项目运行,输入命令行:
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"
选择VIEW->Flame Graph可切换为火焰图:
火焰图从上到下可表示函数的调用顺序,每一个小块代表了一个函数。块长代表了占用CPU的时间。可以看到wolf.(*Wolf).Drink.func1,这个函数的协程占用了大部分CPU时间
mutex-锁分析
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"
问题函数:sync (*Mutex) Unlock。
block-阻塞
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"
图形化操作与上述操作基本一致。
block的命令行操作,其中过滤了cum较小的函数过滤掉了
go tool pprof "http://localhost:6060/debug/pprof/block"
其中过滤掉了cum<=5.92s的函数。