golang 性能分析(2)

golang 性能分析

前言

文章主要用于记忆,怕自己忘记,仅供参考
性能分析,一般都是直接运行应用程序分析性能
结合上章
但是线上的web应用程序遇到问题,怎么分析呢,介绍下我自己的方式

1.普通性能分析

一般采集CPU样板数据代码,这里我只写一种,至于其他的内存和trace采集,可以参考:
https://github.com/hyper0x/go_command_tutorial/blob/master/0.12.md
此文章介绍了各种采集样板数据原理,以及展示方式


import  (
   "runtime/pprof"
   "log"
)
func main() {
   f, err := os.OpenFile("cpu.out", os.O_RDWR|os.O_CREATE, 0700)
   if err != nil {
       return
   }
   defer f.Close()

   pprof.StartCPUProfile(f)
   defer pprof.StopCPUProfile()
}

go run main.go,即可看到cpu.out

方法1:
获取cpu分析png图:go tool pprof -png cpu.out > cpu.png

方法二:
进入命令行:go tool pprof cpu.out
top命令:查看cpu和内存消耗排行版
list:查看某个函数的代码,以及该函数每行代码的指标信息,如果函数名不明确,会进行模糊匹配,比如list main会列出main.main
traces:打印所有调用栈,以及调用栈的指标信息
其他命令可以通过help查看

(2). http在线性能分析

网络一般都是默认引入包
“net/http/pprof”

package main

import (
	_ "net/http/pprof"
)

这种方式一般适用范围很小,看下pprof默认干了什么?

package pprof

import (
	"bufio"
	"bytes"
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http"
	"os"
	"runtime"
	"runtime/pprof"
	"runtime/trace"
	"strconv"
	"strings"
	"time"
)

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

默认pprof包只是在http对应的handle map数据中,设置了几个handlefunc
但是如果我们程序引入了框架,默认的map数据源可能就失效了
所以我们可以收到把这几个handlefunc,放到我们的框架对应的handle中
这样我们就能在线请求上面的性能分析地址了

总览:线程数量,阻塞调用,内存分析 ,协程分析等

1:文件中的http.Handle("/debug/pprof/", http.HandlerFunc(Index)) 放到handle配置中(此handle包含了所有的分析函数)
2:  浏览器访问http://host:port/debug/pprof/

pprof cpu和内存分析说明

方法1:
1:文件中的http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))放到handle配置中
3:设置10s收集一次CPU信息:curl 'http//host:port/debug/pprof/profile?seconds=10' -o cpu.out
4:获取cpu分析png图:go tool pprof -png  cpu.out > cpu.png

方法二:
1,2跟上面想同
3:进入命令行:go tool pprof cput.out
top命令:查看cpu和内存消耗排行版
list:查看某个函数的代码,以及该函数每行代码的指标信息,如果函数名不明确,会进行模糊匹配,比如list main会列出main.main
traces:打印所有调用栈,以及调用栈的指标信息
help查看其他命令

heap 内存跟踪说明

内存泄露情况:
1:goroutine本身的栈所占用的空间造成内存泄露。
2:goroutine中的变量所占用的堆内存导致堆内存泄露,这一部分是能通过heap profile体现出来的。

内存profiling记录的是堆内存分配的情况,以及调用栈信息,并不是进程完整的内存情况。
栈内存的分配是在调用栈结束后会被释放的内存,所以并不在内存profile中。
因为内存profiling是基于抽样和它跟踪的是已分配的内存,而不是使用中的内存,(比如有些内存已经分配,看似使用,但实际以及不使用的内存,比如内存泄露的那部分),所以不能使用内存profiling衡量程序总体的内存使用情况。
heap能帮助我们发现内存问题,但不一定能发现内存泄露问题,内存主要被哪些代码占用了,程序存在内存问题

1:主要看监控系统:随着时间的推进,内存的占用率在不断的提高,这是内存泄露的最明显现象
2:能够对比两个profile文件的差别,观察
go tool pprof -base heap.out heap2.out

1:设置10s收集一次信息:curl 'http//host:port/debug/pprof/heap?seconds=10' -o heap.out
2:获取heap分析png图:go tool pprof -png  heap.out > heap.png

trace 跟踪携程,syscall,垃圾回收说明

1:设置10s收集一次信息:curl 'http//host:port/debug/pprof/trace?seconds=10' -o trace.out
2: 获取trace分析:go tool trace -http="localhost:port"  trace.out
5: 访问:http://localhost:port

总结线个人上程序出现502,504先查看CPU的消耗和内存

cpu消耗比较高当然,自己增加服务器
如果cpu和内存消耗都不高的情况下
最大的可能是gc占用时间比较高,这个时候trace信息很有用了,通过访问trace中url
查询traces信息,可以看到主要是哪些对象占用了大量内存,可以从这部分代码入手
根据我的经验,json.unmarshal的时候,采用的是反射原理,默认会简历大量的临时对象
如果json数据包很多,那么会很快产生gc,而golang的gc默认是暂停整个程序运行的,所以
这种情况,要么修改gc条件比如:export GOGC=200,内存增大到3倍,才开始gc
要么减少json反序列化

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值