go pprof 性能调优

一.pprof

  • Profiling 是指在程序执行过程中,收集能够反映程序执行状态的数据。在软件工程中,性能分析(performance analysis,也称为 profiling),是以收集程序运行时信息为手段研究程序行为的分析方法,是一种动态程序分析的方法。
  • GO中自带两个库可以进行程序分析调优:
    1)runtime/pprof 对于本地只跑一次的程序,例如程序中的某一函数调优,调用 pprof 包提供的函数,手动开启性能数据采集。
    2)net/http/pprof 对于在线服务,对于一个 HTTP Server,访问 pprof 提供的 HTTP 接口,获得性能数据。当然,实际上这里底层也是调用的 runtime/pprof 提供的函数,封装成接口对外提供网络访问。
    一般常用net/http/pprof,操作相对简单
包含的性能数据

  • allocs 和 heap 采样的信息一致,不过前者是所有对象的内存分配,而 heap 则是活跃对象的内存分配

二.net/http/pprof 使用

1)导包,启动端口服务

//只需要在你的程序中加入以下几行代码
import _ "net/http/pprof"
func maim() {
      go func() {
            http.ListenAndServe("0.0.0.0:8686", nil)
      }()
}

原理

在初始化导包的时候,pprof 包会自动注册 handler,即我们调试过程中查看的接口:

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))
}

2)服务启动后,可以浏览器访问

http://127.0.0.1:8686/debug/pprof/

由于网页般数据可读性较差,服务器终端一般用命令行读取数据

# 下载 cpu profile,
go tool pprof http://47.93.238.9:8080/debug/pprof/profile

# 默认手机30S的数据,通过seconds调整时间120s
go tool pprof http://47.93.238.9:8080/debug/pprof/profile?seconds=120     

# 下载 heap profile
go tool pprof http://47.93.238.9:8080/debug/pprof/heap

# 下载 goroutine profile
go tool pprof http://47.93.238.9:8080/debug/pprof/goroutine

# 下载 block profile
go tool pprof http://47.93.238.9:8080/debug/pprof/block

# 下载 mutex profile
go tool pprof http://47.93.238.9:8080/debug/pprof/mutex

3)输入上述命令后,会打开终端交互界面,交互常用命令 top、 list、 traces、 web

- top

获取前20条,cpu占用的函数
flat--- 该函数占时
flat% --- 该函数相对于总耗时的百分比
sum% --- 前面累计每一行flat 占比
cum --- 该函数以及该函数调用的其他函数总耗时
cum --- 对应的百分比

- list 具体函数: 如结合上图 list Eat 直接定位到消耗资源的代码处

- traces 列出函数的调用栈

实战中,首先通过profile,定位cpu消耗暂时较大的函数,然后通过heap定位内存占用较大的函数逻辑。

通过pprof定位性能瓶颈,根据实际问题优化,从而实现性能的提高

三.内存泄漏查找

内存分配既可以发生在堆上也可以在栈上。堆上分配的内存需要垃圾回收或者手动回收(对于没有垃圾回收的语言,例如 C++),栈上的内存则通常在函数退出后自动释放。

什么是内存泄漏

内存泄漏是指程序运行过程中已不再使用的内存,没有被释放,导致这些内存一直无法使用,直到程序结束这些内存才被释放的问题
一般形成主要有两个原因:

  • goroutine 的阻塞
  • GC回收时,无法实现100%的回收

怎么发现内存泄露

1、监控工具: 固定周期对进程内存占用采样,数据可视化后,根据内存占用走势(持续上升)
- 云平台的监控工具,或者建立一个脚本,定时执行采集数据

2、go pprof 间隔一段时间采集文件,对比分析是否存在明显的增量
对比heap
1)通过 go tool pprof http://47.93.238.9:8080/debug/pprof/heap 命令,在间隔一段时间后,分别获取两个文件;
2)go tool pprof -base file1 file2 对比两个文件,top获取对比后占用增加明显的函数块
对比goroutine
1)通过 go tool pprof http://47.93.238.9:8080/debug/pprof/goroutine命令,在间隔一段时间后,分别获取两个文件;
2)go tool pprof -base file1 file2 对比两个文件,top获取对比后占用增加明显的函数块

原文地址:https://www.cnblogs.com/fanzou/p/13528415.html