성능 분석 pprof 및 추적으로 이동

  • 런타임/pprof: 코덱 작업 등과 같은 종료 가능한 코드 블록에 사용되는 분석을 위해 프로그램(비서버)의 실행 데이터를 수집합니다.
  • net/http/pprof: 분석을 위해 HTTP Server의 런타임 데이터를 수집합니다. 웹 애플리케이션 등과 같이 종료할 수 없는 코드 블록에 사용됩니다.

사용되는 장면

메모리 누수 분석'

요약하다

 이동 중 메모리 누수는 일반적으로 고루틴 누수로 인해 발생합니다. 고루틴이 닫히지 않거나 시간 초과 제어가 추가되지 않아 고루틴이 차단된 상태로 남아 GC를 수행할 수 없습니다.

일시적인 메모리 누수

  • 긴 문자열의 세그먼트를 얻으면 긴 문자열이 해제되지 않습니다.
  • 긴 슬라이스의 섹션을 얻으면 긴 슬라이스가 해제되지 않습니다.
  • 긴 슬라이스에 새 슬라이스를 만들면 누출이 발생합니다.

영구 메모리 누수

  • 고루틴 누출
  • time.Ticker가 닫히지 않아 누출이 발생함
  • 종료자로 인해 누출이 발생함
  • 함수 호출을 연기하면 누출이 발생합니다.

Pprof를 사용하는 일반적인 방법( net/http/pprof 포함 ):

1. 네트워크 액세스 방법, 도구로 이동하여 Flame 그래프 보기

프로그램에서 별도의 코루틴을 시작하고, "net/http/pprof" 패키지를 도입하고, 아래와 같이 액세스를 위해 pprof로 다른 포트를 수신합니다.

func setDebug() error {
	if config.C.General.Debug != "" {
		port := strings.Split(config.C.General.Debug, ":")[1]
		log.WithFields(log.Fields{
			"profile":    "http://127.0.0.1:" + port + "/debug/pprof/profile",
			"goroutines": "http://127.0.0.1:" + port + "/goroutines",
		}).Info("open prof debug")
		go func() {
			http.HandleFunc("/goroutines", func(w http.ResponseWriter, r *http.Request) {
				num := strconv.FormatInt(int64(runtime.NumGoroutine()), 10)
				w.Write([]byte(num))
			})
			http.ListenAndServe(config.C.General.Debug, nil)
		}()
	}
	return nil
}

또는 프로그램 청취 포트를 직접 공유하십시오. 다음과 같이 package_ "net/http/pprof" 패키지를 소개하세요.

import (
"fmt"
"net/http"
_ "net/http/pprof"
)

func HelloWorld(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "hello world")
}

func main() {
	http.HandleFunc("/", HelloWorld)

	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		fmt.Println(err)
	}
}

먼저 프로그램을 실행한 다음 터미널 창을 열고 go 도구 명령을 실행합니다. 플레임 그래프 툴을 먼저 설치해야 쉽게 볼 수 있으며, 설치 방법은 아래와 같습니다.

go tool pprof -http=:9000 http://localhost:88/debug/pprof/goroutine?debug=1 (모니터링할 서비스 주소)

9000: 최종적으로 플레임 그래프를 볼 수 있는 포트를 나타내며, 실행 후 기본 브라우저가 사용되며 웹페이지가 자동으로 열립니다.

#현재 모든 고루틴의 스택 추적 보기

이동 도구 pprof http://127.0.0.1:8080/debug/pprof/goroutine

# 120초 기다림

이동 도구 pprof http://127.0.0.1:8080/debug/pprof/profile?seconds=120

Flame 그래프 설치 주소 :

시각적 그래픽 소프트웨어 도구 graphviz(https://graphviz.org/download/)를 다운로드하고 설치합니다. Linux, Windows, Mac 등의 해당 버전을 선택할 수 있으며 시스템 환경 변수에 도구를 추가하는 것을 기억하세요. 그렇지 않으면 오류가 보고됩니다: dot 실행에 실패했습니다. Is Graphviz가 설치되어 있습니까? 오류: exec: "dot ": %PATH%에서 실행 파일을 찾을 수 없습니다. 

여기에 이미지 설명을 삽입하세요.

 

또한 수집 전에 압력 테스트를 수행한 다음 압력 테스트 프로세스 중에 수집할 수 있으므로 분석에 도움이 됩니다 .

  • go-wrk -c=400 -t=8 -n=100000 http://127.0.0.1:8000/api/getReq
  • 400개의 연결, 8개의 스레드, 100,000개의 요청 시뮬레이션

 2. 진 프레임워크, 캡슐화 사용 

"github.com/gin-contrib/pprof"

프레임워크의 항목은 캡슐화됩니다. 프로그램 시작 후 브라우저를 통해 직접 접근이 가능하며, 실행을 위해 go 도구를 사용할 필요가 없습니다. (프로그램 시작 후 먼저 스트레스 테스트 명령을 실행하면 됩니다.)

http://localhost:88/debug/pprof/ 프로그램에 직접 액세스합니다.

특정 매개변수의 의미

  • allocs: 메모리 할당 추상화
  • block: 블로킹 스택의 샘플링 정보
  • cmdline: 프로그램 시작 명령 및 해당 매개변수
  • goroutine: 현재 코루틴의 스택 정보
  • heap: 힙 메모리의 샘플링 정보
  • mutex: 잠금 경쟁의 샘플링 정보
  • 프로필: CPU 사용량 샘플링 정보
  • threadcreate: 시스템 프로그램 생성에 대한 샘플링 정보
  • Trace : 프로그램 실행에 대한 추적 정보

브라우저에서 그래픽 함수 호출 스택 정보를 볼 수 있습니다. 오른쪽 상단 모서리에 있는 막대 VIEW에는 클릭하여 볼 수 있는 몇 가지 옵션이 있는데, Flame Graph이는 전설적인 불꽃 그래프입니다.

Pprof를 사용하는 일반적인 방법( runtime/pprof 포함 ):

도구 유형 애플리케이션 호출은 상대적으로 간단합니다. 주로 런타임/pprof 라이브러리를 사용하여 파일에 데이터를 쓴 다음 보기를 수행합니다.

package  main
import (
"flag"
"log"
"os"
"runtime/pprof"
"sync"
)

var (
	cpu string
	mem string
)

func init() {
	flag.StringVar(&cpu, "cpu", "", "write cpu profile to file")
	flag.StringVar(&mem, "mem", "", "write mem profile to file")
}

func main() {
	flag.Parse()

	//采样 CPU 运行状态
	if cpu != "" {
		f, err := os.Create(cpu)
		if err != nil {
			log.Fatal(err)
		}
		_ = pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

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

	//采样内存状态
	if mem != "" {
		f, err := os.Create(mem)
		if err != nil {
			log.Fatal(err)
		}
		_ = pprof.WriteHeapProfile(f)
		f.Close()
	}
}

func counter() {
	slice := make([]int, 0)
	var c int
	for i := 0; i < 10000; i++ {
		c = i + 1 + 2 + 3 + 4 + 5
		slice = append(slice, c)
	}
	_ = slice
}

func workOnce(wg *sync.WaitGroup) {
	counter()
	wg.Done()
}

main.go --cpu=cpu.pprof --mem=mem.pprof를 실행해 보세요.

go 도구 pprof cpu.pprof

 파일을 클릭하여 엽니다. (전제조건은 graphviz 도구가 설치되어 있어야 한다는 것입니다)

 

 

  설치되지 않은 경우 graphviz나타납니다 Could not execute dot;may need to install graphviz. graphviz를 설치하는 방법은 다음과 같습니다.

brew install graphviz # for macos

apt-get install graphviz # for ubuntu

yum install graphviz # for centos

성능 도구 사용 추적

1. "런타임/추적" 패키지를 사용하세요.

package main

import (
	"fmt"
	"log"
	"os"
	"runtime/trace"
	"sync"
)

func main() {
	//runtime.GOMAXPROCS(1)
	// 1. 创建trace持久化的文件句柄
	f, err := os.Create("trace.out")
	if err != nil {
		log.Fatalf("failed to create trace output file: %v", err)
	}
	defer func() {
		if err := f.Close(); err != nil {
			log.Fatalf("failed to close trace file: %v", err)
		}
	}()

	// 2. trace绑定文件句柄
	if err := trace.Start(f); err != nil {
		log.Fatalf("failed to start trace: %v", err)
	}
	defer trace.Stop()

	var wg sync.WaitGroup
	wg.Add(2)

	go func() {
		fmt.Println(`Hello`)
		wg.Done()
	}()

	go func() {
		fmt.Println(`World`)
		wg.Done()
	}()

	wg.Wait()
}

먼저 창을 열고 실행하세요.

main.go를 실행해 보세요

다른 창을 열고 실행

 도구 추적 이동 -http=localhost:8080 Trace.out

2023/01/03 11:01:57 추적 파싱 중...
2023/01/03 11:01:57 추적 분할 중...
2023/01/03 11:01:57 브라우저를 여는 중입니다. 추적 뷰어는 http://127.0.0.1:8888에서 수신 중입니다.

 추적 보기: 추적 보기
고루틴 분석: 고루틴 분석, 특정 Ctrip 번호 보기
네트워크 차단 프로필: 네트워크 차단 프로필
동기화 차단 프로필: 동기화 차단 프로필
Syscall 차단 프로필: 시스템 호출 차단 프로필
스케줄러 대기 시간 프로필: 스케줄링 지연 프로필, 일반적으로 사용됩니다. , 시간이 소요되는 위치를 분석하는 데 사용됩니다.
사용자 정의 작업: 사용자 정의 작업
사용자 정의 영역: 사용자 정의 영역
최소 mutator 사용률: 최소 Mutator 사용률

참고:

Go 언어 메모리 누수_cqu_jiangzhou의 블로그-CSDN blog_go 메모리 누수

http://liumurong.org/2019/12/gin_pprof/

Go pprof 성능 분석 도구 - 자세한 사용 다이어그램: _dreamer'~ 블로그 - CSDN 블로그_pprof 다이어그램 보는 방법

golang 성능 분석 Trace_raoxiaoya의 블로그-CSDN blog_golang 추적

추천

출처blog.csdn.net/xia_2017/article/details/125664924