Golang使用pprof监控性能及GC调优

作者:峰云就她了 链接:http://xiaorui.cc/?p=3000 來源:个人博客

共 8809 字,阅读需 22 分钟

这两天用golang在写一个监控的agent,发现长时间运行后会有内存泄露的情况,着实让人郁闷半天… 要解决golang泄露的问题,要理解goalng gc那是事情,再就是利用pprof监视golang的运行环境。

这Golang GC垃圾回收我就先不多说了,等我自己深入了解了,会专门找个时间聊这事.

在golang中用来做监控分析的库包,一般用都是pprof库包… pprof可以在两个地方引入:

net/http/pprof
runtime/pprof

其实net/http/pprof中只是使用runtime/pprof包来进行封装了一下,并在http端口上暴露出来。 runtime/pprof可以用来产生dump文件,再使用go tool pprof来分析这运行日志.

使用net/http/pprof可以做到直接看到当前web服务的状态,包括CPU占用情况和内存使用情况等。

这次重点说些pprof web显示的模式,我自己主要是关注heap,profile两个数据源。

关于golang运行环境heap的信息、内存mem

http://localhost:7777/debug/pprof/heap

关于profile、CPU计算百分比

http://localhost:7777/debug/pprof/profile

上面简单介绍了pprof的监控接口,但怎么查看这些数据? 有这么几个查看方式.

交互模式, 可以通过用help查看pprof各种命令。 每次运行后拿到的数据是固定的,不会动态更新该数据。

go tool pprof http://localhost:7777/debug/pprof/heap
go tool pprof http://localhost:7777/debug/pprof/profile

如果你不想使用交互模式,当然这每次都是新数据:

go tool  pprof --text http://localhost:7777/debug/pprof/heap

网页查看模式:

http://localhost:7777/debug/pprof/

下面是我随便写的一段伪业务代码. 大家可以长时间运行这段代码,会发现内存在缓慢的增长中.

#xiaorui.cc
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	_ "net/http/pprof"
	"sync"
	"time"
)

func counter() {
	list := []int{1}
	c := 1
	for i := 0; i < 10000000; i++ {
		httpGet()
		c = i + 1 + 2 + 3 + 4 - 5
		list = append(list, c)
	}
	fmt.Println(c)
	fmt.Println(list[0])
}

func work(wg *sync.WaitGroup) {
	for {
		counter()
		time.Sleep(1 * time.Second)
	}
	wg.Done()
}

func httpGet() int {
	queue := []string{"start..."}
	resp, err := http.Get("http://www.163.com")
	if err != nil {
		// handle error
	}

	//defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		// handle error
	}
	queue = append(queue, string(body))
	return len(queue)
}

func main() {
	flag.Parse()

	//这里实现了远程获取pprof数据的接口
	go func() {
		log.Println(http.ListenAndServe("localhost:7777", nil))
	}()

	var wg sync.WaitGroup
	wg.Add(10)
	for i := 0; i < 100; i++ {
		go work(&wg)
	}

	wg.Wait()
	time.Sleep(3 * time.Second)
}

下面是pprof统计的heaq信息

#xiaorui.cc
$ go tool  pprof --text http://localhost:7777/debug/pprof/heap
Fetching profile from http://localhost:7777/debug/pprof/heap
Saved profile in /Users/ruifengyun/pprof/pprof.localhost:7777.inuse_objects.inuse_space.024.pb.gz
60.81MB of 60.81MB total (  100%)
Dropped 62 nodes (cum <= 0.30MB)
      flat  flat%   sum%        cum   cum%
   56.23MB 92.46% 92.46%    56.23MB 92.46%  bytes.makeSlice
    3.08MB  5.07% 97.53%     3.08MB  5.07%  compress/flate.NewReader
    0.50MB  0.83% 98.36%     0.50MB  0.83%  net/http.(*Transport).dialConn
    0.50MB  0.82% 99.18%     0.50MB  0.82%  net/http.readTransfer
    0.50MB  0.82%   100%     0.50MB  0.82%  net/http.NewRequest
         0     0%   100%    59.31MB 97.53%  bytes.(*Buffer).ReadFrom
         0     0%   100%     3.08MB  5.07%  compress/gzip.(*Reader).readHeader
         0     0%   100%     3.08MB  5.07%  compress/gzip.NewReader
         0     0%   100%    59.31MB 97.53%  io/ioutil.ReadAll
         0     0%   100%    59.31MB 97.53%  io/ioutil.readAll
         0     0%   100%    59.81MB 98.35%  main.counter
         0     0%   100%    59.81MB 98.35%  main.httpGet
         0     0%   100%    59.81MB 98.35%  main.work
         0     0%   100%     0.50MB  0.82%  net/http.(*Client).Get
         0     0%   100%     0.50MB  0.83%  net/http.(*Transport).getConn.func4
         0     0%   100%     3.08MB  5.07%  net/http.(*bodyEOFSignal).Read
         0     0%   100%     3.08MB  5.07%  net/http.(*gzipReader).Read
         0     0%   100%     0.50MB  0.82%  net/http.(*persistConn).readLoop
         0     0%   100%     0.50MB  0.82%  net/http.(*persistConn).readResponse
         0     0%   100%     0.50MB  0.82%  net/http.Get
         0     0%   100%     0.50MB  0.82%  net/http.ReadResponse
         0     0%   100%    60.81MB   100%  runtime.goexit

另外需要说的一点,pprof可以生成一个svg的矢量图,可以通过这svg图确认代码的流程及调用情况. svg是使用graphviz生成的,mac下直接brew install graphviz就能安装,centos下,yum -y install graphviz .

下面是pprof help的使用文档.

#xiaorui.cc
$ go tool  pprof  http://localhost:6060/debug/pprof/heap
Fetching profile from http://localhost:6060/debug/pprof/heap
Saved profile in /Users/ruifengyun/pprof/pprof.localhost:6060.inuse_objects.inuse_space.032.pb.gz
Entering interactive mode (type "help" for commands)
(pprof) help

 Commands:
   cmd [n] [--cum] [focus_regex]* [-ignore_regex]*
       Produce a text report with the top n entries.
       Include samples matching focus_regex, and exclude ignore_regex.
       Add --cum to sort using cumulative data.
       Available commands:
         callgrind    Outputs a graph in callgrind format
         disasm       Output annotated assembly for functions matching regexp or address
         dot          Outputs a graph in DOT format
         eog          Visualize graph through eog
         evince       Visualize graph through evince
         gif          Outputs a graph image in GIF format
         gv           Visualize graph through gv
         list         Output annotated source for functions matching regexp
         pdf          Outputs a graph in PDF format
         peek         Output callers/callees of functions matching regexp
         png          Outputs a graph image in PNG format
         proto        Outputs the profile in compressed protobuf format
         ps           Outputs a graph in PS format
         raw          Outputs a text representation of the raw profile
         svg          Outputs a graph in SVG format
         tags         Outputs all tags in the profile
         text         Outputs top entries in text form
         top          Outputs top entries in text form
         tree         Outputs a text rendering of call graph
         web          Visualize graph through web browser
         weblist      Output annotated source in HTML for functions matching regexp or address
   peek func_regex
       Display callers and callees of functions matching func_regex.

   dot [n] [focus_regex]* [-ignore_regex]* [>file]
       Produce an annotated callgraph with the top n entries.
       Include samples matching focus_regex, and exclude ignore_regex.
       For other outputs, replace dot with:
       - Graphic formats: dot, svg, pdf, ps, gif, png (use > to name output file)
       - Graph viewer:    gv, web, evince, eog

   callgrind [n] [focus_regex]* [-ignore_regex]* [>file]
       Produce a file in callgrind-compatible format.
       Include samples matching focus_regex, and exclude ignore_regex.

   weblist func_regex [-ignore_regex]*
       Show annotated source with interspersed assembly in a web browser.

   list func_regex [-ignore_regex]*
       Print source for routines matching func_regex, and exclude ignore_regex.

   disasm func_regex [-ignore_regex]*
       Disassemble routines matching func_regex, and exclude ignore_regex.

   tags tag_regex [-ignore_regex]*
       List tags with key:value matching tag_regex and exclude ignore_regex.

   quit/exit/^D
         Exit pprof.

   option=value
       The following options can be set individually:
           cum/flat:           Sort entries based on cumulative or flat data
           call_tree:          Build context-sensitive call trees
           nodecount:          Max number of entries to display
           nodefraction:       Min frequency ratio of nodes to display
           edgefraction:       Min frequency ratio of edges to display
           focus/ignore:       Regexp to include/exclude samples by name/file
           tagfocus/tagignore: Regexp or value range to filter samples by tag
                               eg "1mb", "1mb:2mb", ":64kb"

           functions:          Level of aggregation for sample data
           files:
           lines:
           addresses:

           unit:               Measurement unit to use on reports

           Sample value selection by index:
            sample_index:      Index of sample value to display
            mean:              Average sample value over first value

           Sample value selection by name:
            alloc_space        for heap profiles
            alloc_objects
            inuse_space
            inuse_objects

            total_delay        for contention profiles
            mean_delay
            contentions

   :   Clear focus/ignore/hide/tagfocus/tagignore
(pprof)

根据pprof的统计信息我们可以找到CPU过度计算及内存泄露的大概的点。 现在越来越觉得Golang gc有些让人摸不清头脑. 看来有必要深入学习Golang gc垃圾回收原理.

END

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2018-03-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏灯塔大数据

技术| Python的从零开始系列连载(三十)

为了解答大家学习Python时遇到各种常见问题,小灯塔特地整理了一系列从零开始的入门到熟练的系列连载,每周五准时推出,欢迎大家学积极学习转载~

952
来自专栏Golang语言社区

使用Go语言框架进行web开发笔记

前言 关于golang的web开发有不少框架,例如 martini, gin, revel,gorilla等。 之前玩过revel,感觉封装的太多了,作为一个小...

4227
来自专栏Python中文社区

用Python列出哔哩哔哩up主剧集目录

專 欄 ❈丁果,Python中文社区作者。对django、pyqt、opencv、tornado感兴趣。 GitHub:https://github.com/...

22410
来自专栏积累沉淀

Python快速学习第十二天--生成器和协程

yield指令,可以暂停一个函数并返回中间结果。使用该指令的函数将保存执行环境,并且在必要时恢复。 生成器比迭代器更加强大也更加复杂,需要花点功夫好好理解贯...

8275
来自专栏信安之路

2017-NSCTF-PWN

这次比赛值得吐槽的地方很多,但是我要忍住,先讲正经的。 这次总结比赛的两道pwn,都是栈溢出类型的,比较简单。先放上题目链接:http://pan.baidu....

940
来自专栏程序你好

C# API中的模型和它们的接口设计

962
来自专栏IMWeb前端团队

【原译】javascript中的错误处理

本文作者:IMWeb ouven 原文出处:IMWeb社区 未经同意,禁止转载 【原译】javascript中的正确错误处理 A Guide to P...

2469
来自专栏程序员宝库

JAVA 中异常处理的最佳实践

前言 异常处理的问题之一是知道何时以及如何去使用它。我会讨论一些异常处理的最佳实践,也会总结最近在异常处理上的一些争论。 作为程序员,我们想要写高质量的能够解决...

3178
来自专栏*坤的Blog

Java分层概念(转)

9044
来自专栏java一日一条

深入理解 Java 中的 try-with-resource

众所周知,所有被打开的系统资源,比如流、文件或者Socket连接等,都需要被开发者手动关闭,否则随着程序的不断运行,资源泄露将会累积成重大的生产事故。

1622

扫码关注云+社区

领取腾讯云代金券