指标采集


main.go中添加:

1
2
3
4
5
6
7
8
9
go func() {
fmt.Println(http.ListenAndServe(fmt.Sprintf("127.0.0.1:%s", "6060"), nil))
}()
// 开启锁争用分析(默认不开启锁的竞争分析,需要调用runtime.SetMutexProfileFraction进行设置)
// (mutex主要用于查看锁争用导致的休眠时间,这有助于排查由于锁争用导致CPU利用率不足的问题)
goruntime.SetMutexProfileFraction(1)
// 开启block分析(同上,默认不开启)
// 在程序中,除了锁的争用会导致阻塞之外,很多逻辑都会导致阻塞,比如网络请求超时、IO阻塞等
goruntime.SetBlockProfileRate(1)


在压测时保存下各种指标信息:

1
curl http://127.0.0.1:6060/debug/pprof/heap -o heap_cui.out && curl http://127.0.0.1:6060/debug/pprof/goroutine -o goroutine_cui.out && curl http://127.0.0.1:6060/debug/pprof/mutex -o mutex_cui.out && curl http://127.0.0.1:6060/debug/pprof/profile?seconds=30 -o profile_cui.out && curl http://127.0.0.1:6060/debug/pprof/block -o block_cui.out

一般很少用到trace,且trace文件体积会比较大,上百M(另外几个指标的文件大小都是几百k到几M级); 可以通过
curl http://127.0.0.1:6060/debug/pprof/trace?seconds=30 -o trace_cui.out来采集


指标分析


以分析内存分配为例:

go tool pprof heap_cui.out,而后在交互式的命令行中输入web,可以查看内存分配信息

但这种方式无法查看更详细的内容,更建议通过指定在浏览器中打开这种方式查看: go tool pprof --http :9091 heap_cui.out

可以有各种选择

其中Flame Graph即火焰图形式展现, 在最下方一行,占据越多宽度的,就是内存分配最多的点;

下一步就可以根据这些信息进行定位,进而优化


看起来“人畜无害”的Go官方库提供的一些字符串操作方法,如 strings.ToUpper,strings.ToLower,strings.SplitN, errors.New 为什么会成为性能瓶颈?

分析一下不难发现,这几个方法都有内存分配

1
2


Go memory ballast: How I learnt to stop worrying and love the heap

https://blog.csdn.net/wohu1104/article/details/113795455

https://mytechshares.com/2021/11/22/go-error-best-practice/#1-github-com-pkg-errors-%E5%BA%93%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90-warapper-error