Go代码性能分析:定位瓶颈
性能优化是开发者的关键任务之一,尤其是在处理Go高负载系统时。但在优化之前,必须准确知道哪些代码段是瓶颈。为此,我们需要性能分析——收集和分析程序执行的指标。
在本文中,我们将探讨如何使用内置工具对Go应用程序进行性能分析:pprof和trace。您将学习如何发现CPU、内存、锁和goroutine方面的问题点,以及如何解读获得的数据。
什么是性能分析以及为什么需要它?
性能分析是在程序执行期间收集其运行数据的过程。这些数据有助于回答以下问题:
- 哪些函数消耗最多的CPU时间?
- 哪里分配了大量内存?
- 哪些goroutine被阻塞以及被什么阻塞?
- 系统调用或I/O操作花费了多少时间?
Go开箱即用地提供了强大的性能分析工具。主要工具是用于Web应用程序的net/http/pprof和用于CLI工具的runtime/pprof。
pprof工具:CPU和内存分析
pprof是Go性能分析的主要工具。它能够收集CPU、内存、锁、goroutine和互斥锁竞争的分析数据。
将pprof添加到Web应用程序
连接性能分析最简单的方法是导入net/http/pprof包:
package main
import ( "net/http" _ "net/http/pprof" // 注册pprof处理器)
func main() { // 您的应用程序 http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil)}之后,在地址/debug/pprof/处将提供各种分析数据。例如:
/debug/pprof/profile— CPU分析(默认30秒)/debug/pprof/heap— 内存分析(堆)/debug/pprof/goroutine— 所有goroutine的转储/debug/pprof/block— 阻塞分析
收集CPU分析数据
要收集CPU分析数据,请使用以下命令:
go tool pprof http://localhost:8080/debug/pprof/profile?seconds=30收集完成后,将打开一个交互式pprof控制台。最有用的命令:
top— 显示消耗最多CPU的函数list <函数名>— 显示逐行时间分解web— 在浏览器中打开调用图(需要Graphviz)peek <函数名>— 显示调用者和被调用函数
top输出示例:
Showing nodes accounting for 3.50s, 70% of 5.00s total flat flat% sum% cum cum% 1.20s 24.00% 24.00% 1.20s 24.00% encoding/json.(*Decoder).Decode 0.80s 16.00% 40.00% 0.80s 16.00% runtime.mallocgc 0.60s 12.00% 52.00% 1.80s 36.00% main.processData 0.50s 10.00% 62.00% 0.50s 10.00% runtime.memmove 0.40s 8.00% 70.00% 0.40s 8.00% strings.ToLower收集内存分析数据
要分析内存使用情况:
go tool pprof http://localhost:8080/debug/pprof/heappprof中用于内存分析的重要命令:
top— 分配最多内存的函数sample_index=alloc_space— 切换到已分配内存总量sample_index=inuse_space— 切换到当前使用的内存tr