程序在运行过程中,总是会遇到一些功能问题,比如cpu运用率莫名奇妙的飙升、内存运用率奇高级,轻者导致接口响应速度变慢,重者导致系统崩溃,无法提供服务。
这时候,咱们就需要对程序进行功能剖析,找出问题所在。在golang中,咱们能够运用pprof进行功能剖析。今日,咱们持续丰厚咱们的gRPC服务,为其增加pprof组件。
pprof简介
Go语言的pprof库,能够用于剖析Go程序的功能瓶颈,它的主要功能有:
pprof相关包主要有两个:
- runtime/pprof:实时收集程序运行时数据以供剖析。
- net/http/pprof:在runtime/pprof基础上,提供相关http节课,能够经过相关url来检查功能剖析数据。
增加pprof
咱们此次运用net/http/pprof库,需要监听http端口,来提供相关功能剖析服务。
咱们在服务端程序中增加如下代码:
go func() {
err = http.ListenAndServe(":6060", nil)
if err != nil {
logger.Fatal("pprof start failed", zap.Error(err))
}
}()
上面,咱们启用了一个监听6060端口的http服务来收集功能剖析数据。
接下来,咱们从头编译服务端程序并发动:
make consuldemo-build && ./consuldemo/bin/server
然后,咱们在浏览器中访问http://localhost:6060/debug/pprof/,能够看到如下界面:
其间:
- allocs:一切的前史内存分配状况。
- block:堵塞状况。
- cmdline:指令行调用信息。
- goroutine:协程状况。
- heap:当时活跃目标的堆内存分配收集状况。
- mutex:互斥锁信息。
- profile:cpu运用状况。
- threadcreate:新的操作系统线程创立状况。
- trace:当时程序的履行trace。
更多信息,能够检查源代码(net/http/pprof/pprof.go)或参考文档。
测试
收集曩昔20s的cpu运用数据
咱们履行如下指令,来收集曩昔20s的cpu运用数据:
go tool pprof -seconds 20 -http=localhost:6061 http://localhost:6060/debug/pprof/profile
在上面的指令中,咱们从6060端口收集数据,收集时刻为20s,并在本地6061端口发动http服务,用于展现收集到的数据。 履行成功后,将主动翻开浏览器(http://localhost:6061/ui/):
咱们的gRPC服务处于闲暇状况,所以能够看到大部分时刻用于findRunnable(查找待运行的写成)。
收集曩昔20s的堆内存运用状况
咱们履行如下指令,来收集曩昔20s的堆内存运用状况:
go tool pprof -seconds 20 -http=localhost:6061 http://localhost:6060/debug/pprof/heap
履行成功后,将主动翻开浏览器(http://localhost:6061/ui/): 咱们点击SAMPLE-objects,检查目标分配状况:
没有任何数据。这是因为咱们的服务处于闲暇状况,没有进行任何内存分配。 下面,咱们在服务端程序中增加如下测试代码:
func allocDebug() {
// 分配1MB内存
_ = make([]byte, 1<<20)
}
func main() {
// ...
go func() {
for {
allocDebug()
time.Sleep(time.Second)
}
}()
// ...
}
在上面的代码中,咱们每隔一秒,都会新建一个切片,为其分配1M字节的内存 咱们从头编译并发动服务端程序:
make consuldemo-build && ./consuldemo/bin/server
从头履行收集指令:
go tool pprof -seconds 20 -http=localhost:6061 http://localhost:6060/debug/pprof/heap
履行成功后,将主动翻开浏览器(http://localhost:6061/ui/),咱们点击SAMPLES->alloc_objects,检查目标分配状况: 能够看到,几乎全部目标都由allocDebug函数分配。
实践工作中,不一定非要采用这种方法来进行功能剖析,如果知道详细哪个接口产生了瓶颈,能够直接在本地测试这个接口对应的方法。
参考文档
本文由mdnice多渠道发布