第八章--性能优化--pprof详细研究

接着上次的博客: https://www.cnblogs.com/ITPower/articles/12315637.html

pprof的基本操作,上次博客有记录,这里进一步研究pprof

接下来开始今天的学习内容. 计划今天研究以下几个部分的内容

1. pprof扩展

  a. 在单元测试testing.B中测试检测程序的性能

  b. web项目中检测程序的性能

2. pprof的使用,以及如何看生成的svg图.

3. 使用pprof分析近期做过的一个beego项目. 详见另一篇博客: https://www.cnblogs.com/ITPower/articles/12324659.html

4. 调研pprof是否能够使用在生成环境. 

5. 研究testing.T,testing.B testing.TB testing.N的区别: 详见博客https://www.cnblogs.com/ITPower/articles/12320577.html

 

一. pprof扩展

Go语言自带了强大的性能测试工具pprof,位于 net/http 包下的 pprof, 官方文档

go中有pprof包来做代码的性能监控,在两个地方有包:net/http/pprof 和 runtime/pprof

其实net/http/pprof中只是使用runtime/pprof包来进行封装了一下,并在http端口上暴露出来.

  • net/http/pprof : 可以做到直接看到当前 web 服务的状态,包括 CPU 占用情况和内存使用情况等。如果服务是一直运行的,如 web 应用,可以很方便的使用第一种方式 import "net/http/pprof"。
  • runtime/pprof : 可以用来产生 dump 文件,再使用 Go Tool PProf 来分析这运行日志。

 

我们研究pprof的使用从两个方面研究 :

  1. 如何查看单元测试中对性能的测试分析

  2. 查看web服务的性能

 

1. 查看单元测试中对性能的测试分析

我们借用上一次的一个例子. 对异常处理的代码部分进行性能分析

第一步: 写性能分析的测试用例. 

比如: 我们模拟用户错误的输出情况

func BenchmarkWrapError(t *testing.B) {
    h := handlerUserError
    code := 400
    message := "user error"

    for i := 0; i < t.N ; i ++  {
        f := WrapError(h)
        // 模拟Request和response
        response := httptest.NewRecorder()
        request := httptest.NewRequest(http.MethodGet,http://www.baidu.com",nil)
        f(response,request)
        读取reponse返回的body
        b,_ := ioutil.ReadAll(response.Body)
        body := strings.Trim(string(b),1)">\n)
        if code != response.Code || message != body {
            t.Errorf(except--code: %d,message: %s \n actual--code:%d,message:%s
go test -bench . -cpuprofile cpu.out

第三步: 执行pprof分析

go tool pprof cpu.out

 第四步: 输入web,会生成一个svg的文件,然后使用浏览器查看视图. 

 

 

 

 

从图中可以看出每一步花费的时间大概是多少. 其中哪一个步骤花费的时间最长. 然后我们就可以针对其进行优化了

备注: 要想以web视图的方式查看上述结果,需要下载graphviz,下载方式参考https://www.cnblogs.com/ITPower/articles/12315637.html的第四点,附截图

 

 2. 查看web服务的性能

第一步: import 增加net/http/pprof包  

import(
    _ net/http/pprof
)

第二步: 打开http端的监听端口

go func() {
        http.ListenAndServe(localhost:8888

 

 

 这个页面分为两部分. 第一部分是当前服务的使用情况. 第二部分,对命令的解析

使用情况截图如下

 

 

 Count 表示当前服务使用数,比如2,是消耗内存的进程数. 21表示线程创建数,2 表示历史数据. 等等

 Profile 是性能指标名

 

命令说明如下:

  • allocs: 过去所有内存分配的样本
  • block: 堆栈导致对原始同步的阻塞
  • cmline: 当前程序的命令行调用
  • goroutine: 当前所有goroutine的堆栈跟踪
  • heap: 活动对象内存分配的采样。您可以指定gc GET参数以在获取堆样本之前运行GC。
  • mutex: 竞争互斥持有人的堆栈痕迹
  • profile: CPU配置文件。您可以在GET参数中指定持续时间。获取概要文件后,请使用go tool pprof命令调查文件。
  • threadcreate: 导致创建新OS线程的堆栈跟踪
  • trace: 当前程序执行的痕迹。您可以在GET参数中指定持续时间。获取跟踪文件后,使用go工具trace命令调查跟踪。

第四步: 通过Graphviz,查看heap 

从图中看,cpu的使用是0,heap的使用是2,所以,我们查看heap. 

go tool pprof http:127.0.0.1:8888/debug/pprof/heap

接下来我们可以通过help 查看pprof都有哪些命令. 常用的命令有. tree,top,web

我们用tree查看内存的使用情况

 

 

还可以使用top查看最消耗内存的地方

 

 

接下来还是使用web查看视图

 

 

 视图更加直观,哪一步消耗了多少内存

 

第五步: 模拟并发,测试性能

这样的程序都是刚刚运行,所以内存消耗,cpu消耗都比较少. 接下来我们模拟大量请求,试一试性能如何

 1. 下载一个模拟http请求的工具wrk(模拟现实,了解系统瓶颈,将服务器置于一个繁忙的状态,就像生产环境一样. ),下载地址: https://github.com/wg/wrk.git

在github上也有这个工具的介绍, 

git clonehttps:github.com/wg/wrk.git
cd wrk
make

备注: 整个操作参考github上的说明即可.

2. 安装好wrk以后,模拟批量请求

./wrk -c400 -t8 -d5m http:localhost:8899/v1/user/login

我模拟的是批量登录,参数含义如下

  • -c400: 我们有400个连接可以保持打开状态
  • -t8 :意味着我们使用8个线程来构建请求
  • -d5m 表示测试时间将持续5分钟

3. 在浏览器输入

http:localhost:8899/debug/pprof/

查看使用情况

 

4. awk执行完以后,查看执行结果汇总

5. 接下来用go tool pprof 查看 heap

go tool pprof -alloc_space/-inuse_space http:localhost:8899/debug/pprof/heap
  • -alloc_space: 过去使用的内存数据
  • -inuse_space: 正在使用的内存数据

返回的视图

 

                                                                                                  

                                                                                       

 

 

 

 方框越大,表示内存消耗越多.  

 

 

 

 

 

参考文献:

1. https://blog.csdn.net/guyan0319/article/details/85007181

2. https://www.cnblogs.com/mrblue/p/9555118.html

3. https://www.jianshu.com/p/aa9b148e90e5

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


类型转换 1、int转string 2、string转int 3、string转float 4、用户结构类型转换
package main import s &quot;strings&quot; import &quot;fmt&quot; var p = fmt.Println func main() { p(&quot;Contains: &quot;, s.Contains(&quot;test&quo
类使用:实现一个people中有一个sayhi的方法调用功能,代码如下: 接口使用:实现上面功能,代码如下:
html代码: beego代码:
1、读取文件信息: 2、读取文件夹下的所有文件: 3、写入文件信息 4、删除文件,成功返回true,失败返回false
配置环境:Windows7+推荐IDE:LiteIDEGO下载地址:http://www.golangtc.com/downloadBeego开发文档地址:http://beego.me/docs/intro/ 安装步骤: 一、GO环境安装 二、配置系统变量 三、Beego安装 一、GO环境安装 根
golang获取程序运行路径:
Golang的文档和社区资源:为什么它可以帮助开发人员快速上手?
Golang:AI 开发者的实用工具
Golang的标准库:为什么它可以大幅度提高开发效率?
Golang的部署和运维:如何将应用程序部署到生产环境中?
高性能AI开发:Golang的优势所在
本篇文章和大家了解一下go语言开发优雅得关闭协程的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。1.简介本文将介绍首先为什么需要主...
这篇文章主要介绍了Go关闭goroutine协程的方法,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。1.简介本文将介绍首先为什么需要主动关闭gor...
本篇文章和大家了解一下go关闭GracefulShutdown服务的几种方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。目录Shutdown方法Regi...
这篇文章主要介绍了Go语言如何实现LRU算法的核心思想和实现过程,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。GO实现Redis的LRU例子常
今天小编给大家分享的是Go简单实现多租户数据库隔离的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会...
这篇“Linux系统中怎么安装NSQ的Go语言客户端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希
本文小编为大家详细介绍“怎么在Go语言中实现锁机制”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么在Go语言中实现锁机制”文章能帮助大家解决疑惑,下面...
今天小编给大家分享一下Go语言中interface类型怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考