编码千行,接口百个。
测试通过,成功上线。
性能不佳,被迫下线!
这是已经发生或者将来可能发生的CI/CD。性能优化无止尽,掌握方法更重要。这篇文章不是介绍如何优化,而是分享如何分析系统瓶颈的方式方法。
Go语言的生态相对完整,有着丰富而强大的第3方。Golang性能分析官方提供了工具链。
PProf: 主要分析运行时程序的CPU,内存,锁和Goroutine占用情况
- runtime/pprof: 分析非HTTP服务程序的运行时数据
- net/http/pprof: 分析HTTP服务程序的运行时数据。net/http/pprof基于runtime/pprof开发封装。
Trace: 主要侧重运行时非聚合信息。例如goroutines在执行时会执行哪些操作?多长时间?什么时候阻止?哪里?谁解锁他们?GC如何影响个别goroutines的执行?
https://docs.google.com/document/u/1/d/1FP5apqzBgr7ahCCgFO-yoVhk4YZrNIDNf9RybngBc14/pub
package main
import (
"net/http"
"net/http/pprof"
)
func hiHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hi"))
}
func main() {
r := http.NewServeMux()
r.HandleFunc("/", hiHandler)
// Register pprof handlers
r.HandleFunc("/debug/pprof/", pprof.Index)
r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
r.HandleFunc("/debug/pprof/profile", pprof.Profile)
r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
r.HandleFunc("/debug/pprof/trace", pprof.Trace)
http.ListenAndServe(":8080", r)
}
Types of profiles available:
Count Profile
1 allocs #程序启动至今内存分配情况
0 block #堆栈跟踪导致阻塞同步原语
0 cmdline #程序启动命令及参数
13 goroutine #当前所有协程的堆栈信息
1 heap #堆上内存分配情况信息
0 mutex #锁信息
0 profile #CPU分析文件,下载后go tool pprof分析查看
9 threadcreate #OS创建线程的调用栈信息
0 trace #跟踪当前程序的执行情况,下载后go tool trace分析查看
http://192.168.1.101:8080/debug/pprof/allocs?debug=1
allocs 页面显示了每个内存分配的调用栈。
1: 16 [1: 16] 当前存活对象的数量:存活对象已经占用的内存[分配的总的数量:所有分配已经占用的内存]
http://192.168.1.101:8080/debug/pprof/goroutine?debug=1
goroutine profile: total 13(注解: 表示goroutine总数)
3 @ 0x103052f 0x103fa78 0x130b7d8 0x105cc41 (数量 @ 已经每个goroutine的地址,及调用栈)
# 0x130b7d7 database/sql.(*DB).connectionOpener+0xe7 /usr/local/Cellar/go/1.12/libexec/src/database/sql/sql.go:1000
3 @ 0x103052f 0x103fa78 0x130b90b 0x105cc41
# 0x130b90a database/sql.(*DB).connectionResetter+0xfa /usr/local/Cellar/go/1.12/libexec/src/database/sql/sql.go:1013
....
....
go tool pprof http://192.168.1.101:8080/debug/pprof/heap?seconds=60 Type: inuse_space Time: Sep 2, 2019 at 11:02pm (CST) Entering interactive mode (type "help" for commands, "o" for options) (pprof) web
可以查看内存分配情况
点击 trace下载trace文件。go tool trace ~/Downloads/trace
View trace #跟踪前程序执行情况,默认是30s可以通过seconds=xx指定时间
Goroutine analysis #Goroutine情况分析
Network blocking profile (⬇) #网络阻塞分析文件
Synchronization blocking profile (⬇) #同步阻塞分析
Syscall blocking profile (⬇) #系统调用阻塞分析
Scheduler latency profile (⬇) #调度延迟概况
User-defined tasks #用户定义任务
User-defined regions #用户定义区
Minimum mutator utilization #最小的mutator利用率
点击goroutines;
启动goroutines及数量。点击 net/http.(*conn).serve
包括goroutine ID, 运行总时间及执行时间、网络等待、同步调用阻塞时间、系统调用阻塞时间、调度延迟时间和GC
点击View trace显示以时间为轴的Heap内存分配、Goroutines、物理线程、定时器、系统调用和虚拟处理器的执行情况。
参考文献-1 介绍的比较详细,这里就不重复了。后续会继续更新。
参考文献
-
https://juejin.im/post/5d27400151882530af139a85
-
https://about.sourcegraph.com/go/an-introduction-to-go-tool-trace-rhys-hiltner