使用pprof对rpc服务进行性能分析 | 青训营笔记

311 阅读2分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 15 天

它是一个RPC框架不是Web框架,不支持浏览器用URL访问,所以也就没法跟web框架使用pprof一样,直接设置pprof的相关路由。但是我们可以换个角度来看这个问题,pprof做CPU分析原理是按照一定的频率采集程序CPU(包括寄存器)的使用情况,确定应用程序在主动消耗 CPU 周期时花费时间的位置。所以我们可以在gRPC服务启动时,异步启动一个监听其他端口的HTTP服务,通过这个HTTP服务间接获取gRPC服务的分析数据。

使用pprof收集进程数据

首先匿名引入net/http/pprof包,这个HTTP的复用器默认就会注册pprof相关的路由。

在服务的启动类中增加以下几行代码即可

runtime.SetBlockProfileRate(1)
	go func() {
		http.ListenAndServe(":10001", nil)
	}()

在启动程序的最开端,调用runtime.SetBlockProfileRate(1)指示对阻塞超过1纳秒的goroutine进行数据采集。

此项不是必须设置

注意:所监听的端口为pprof采集数据所用端口,服务启动后就能通过{server_ip}:10001/debug/pprof查看CPU的使用情况了,而pprof也会自动生成报告在{server_ip}:10001/debug/pprof/profile

使用pprof进行可视化分析

在命令行运行以下命令

 go tool pprof -http=":8080" "http://127.0.0.1:10001/debug/pprof/profile"

同时访问相关端口,访问期间上文所起的pprof会对该服务运行期间的cpu数据进行收集,等待一段时间可以通过http://localhost:8080/ui/进行可视化浏览性能报告

可视化界面提供了调用链路以及火焰图等查看方式 image-20230226234526894

image-20230226234549323

缺陷

尽管pprof是一个分析Go程序性能的强大工具,但它也有一些局限和缺陷:

  1. 抽样偏差:pprof通过在固定间隔内对程序的执行进行抽样并收集堆栈跟踪来工作。然而,这种方法可能会引入偏差和不准确性。
  2. 难以调试多线程程序:在多线程程序中,pprof的输出可能会变得复杂和难以解释,使得程序的调试更加困难。
  3. 对内存分配的跟踪不完整:尽管pprof可以提供有关程序内存使用情况的信息,但对于程序中的所有内存分配情况的跟踪并不完整。
  4. 对高并发程序的支持不足:在高并发程序中,pprof的性能可能会受到影响,因为抽样和跟踪数据需要花费更多的时间和资源。

引用

部分内容来自: