程序在运行过程中,总是会遇到一些功能问题,比如cpu运用率莫名奇妙的飙升、内存运用率奇高级,轻者导致接口响应速度变慢,重者导致系统崩溃,无法提供服务。

这时候,咱们就需要对程序进行功能剖析,找出问题所在。在golang中,咱们能够运用pprof进行功能剖析。今日,咱们持续丰厚咱们的gRPC服务,为其增加pprof组件。

pprof简介

Go语言的pprof库,能够用于剖析Go程序的功能瓶颈,它的主要功能有:

  • 提供可视化的web界面。
  • cpu运用状况剖析。
  • 内存运用状况剖析。
  • 堵塞剖析。
  • 互斥锁剖析。
  • 协程剖析。

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/,能够看到如下界面:

gRPC入门系列之6-增加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入门系列之6-增加pprof

咱们的gRPC服务处于闲暇状况,所以能够看到大部分时刻用于findRunnable(查找待运行的写成)。

收集曩昔20s的堆内存运用状况

咱们履行如下指令,来收集曩昔20s的堆内存运用状况:

go tool pprof -seconds 20 -http=localhost:6061 http://localhost:6060/debug/pprof/heap

履行成功后,将主动翻开浏览器(http://localhost:6061/ui/):

gRPC入门系列之6-增加pprof
咱们点击SAMPLE-objects,检查目标分配状况:
gRPC入门系列之6-增加pprof

没有任何数据。这是因为咱们的服务处于闲暇状况,没有进行任何内存分配。 下面,咱们在服务端程序中增加如下测试代码:

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,检查目标分配状况:

gRPC入门系列之6-增加pprof
能够看到,几乎全部目标都由allocDebug函数分配。

实践工作中,不一定非要采用这种方法来进行功能剖析,如果知道详细哪个接口产生了瓶颈,能够直接在本地测试这个接口对应的方法。

参考文档

本文由mdnice多渠道发布