代码上线前可以通过压测可以获知系统的性能,例如每秒能处理的请求数,平均响应时间,错误率等指标。可以对性能有初步的估计
但是压测是线下的模拟流量,线上可能会遇到高并发、大流量,不靠谱的上下游,突发的尖峰流量等等场景,这些都是不可预知的。
线上突然大量报警,接口超时,错误数增加,除了看日志、监控,就是用性能分析工具分析程序的性能,找到瓶颈。当然,一般这种情形不会让你有机会去分析,降级、限流、回滚才是首先要做的,要先止损。回归正常之后,通过线上流量回放,或者压测等手段,制造性能问题,再通过工具来分析系统的瓶颈。
一般而言,性能分析主要关注 CPU、内存、磁盘 IO、网络这些指标。
Profiling 是指在程序执行过程中,收集能够反映程序执行状态的数据。在软件工程中,性能分析(performance analysis,也称为 profiling),是以收集程序运行时信息为手段研究程序行为的分析方法,是一种动态程序分析的方法。
pprof 采样数据主要有三种获取方式:
拿 CPU profiling 举例,增加两行代码,调用 pprof.StartCPUProfile 启动 cpu profiling,调用 pprof.StopCPUProfile() 将数据刷到文件里:
import "runtime/pprof"
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
func main() {
// …………
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
// …………
}
启动一个端口(和正常提供业务服务的端口不同)监听 pprof 请求:
import _ "net/http/pprof"
go func() {
log.Println(http.ListenAndServe("localhost:8080", nil))
}()
pprof 包会自动注册 handler, 处理相关的请求:
// src/net/http/pprof/pprof.go:71
func init() {
http.Handle("/debug/pprof/", http.HandlerFunc(Index))
http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
http.Handle("/debug/pprof/trace", http.HandlerFunc(Trace))
}
启动服务后,直接在浏览器访问:
http://127.0.0.1:8080/debug/pprof/
可以得到以下内容
可以直接点击上面的链接,进入子页面,查看相关的汇总信息
点击 profile 和 trace 则会在后台进行一段时间的数据采样,采样完成后,返回给浏览器一个 profile 文件,之后在本地通过 go tool pprof 工具进行分析。
当我们下载得到了 profile 文件后,执行命令:
go tool pprof ~/Downloads/profile
就可以进入命令行交互式使用模式。执行 help 可以查看帮助信息。
直接使用如下命令,则不需要通过点击浏览器上的链接就能进入命令行交互模式:
go tool pprof http://127.0.0.1:8080/debug/pprof/profile
当然也是需要先后台采集一段时间的数据,再将数据文件下载到本地,最后进行分析。上述的 Url 后面还可以带上时间参数:?seconds=60,自定义 CPU Profiling 的时长。
# 下载 cpu profile,默认从当前开始收集 30s 的 cpu 使用情况,需要等待 30s
go tool pprof http://127.0.0.1:8080/debug/pprof/profile
# wait 60s
go tool pprof http://127.0.0.1:8080/debug/pprof/profile?seconds=60
进入交互式模式之后,比较常用的有 top、 list、 web 等命令。
除了 cpu 使用情况外,线上问题排查还需要关注内存使用问题:
# 下载内存使用svg图到本地
go tool pprof -inuse_space -cum -svg http://ip:port/debug/pprof/heap > heap_inuse.svg
在上一节进入交互式模式之后,执行web 命令时,可以查看 svg 图,如果遇到以下错误
failed to execute dot. Is Graphviz installed? Error: exec: "dot": executable file not found in $PATH
说明需要安装 Graphviz。在mac上可以通过 brew install Graphviz 进行安装,并配置环境变量,在~/.zshrc中写入
export PATH="$PATH:/usr/local/Cellar/graphviz/2.40.1/bin"
其中2.40.1是版本号,随安装版本变化更改。写入文件之后保存,并执行source ~/.zshrc
额外说明一点,其中有依赖包可能需要安装svn,可以通过brew install svn进行安装
在交互模式下输入web 命令会自动下载 svg 文件,通过浏览器打开就可以看见图像
,大致如下