Backend

Go pprof를 활용한 성능 프로파일링 가이드

2025-12-304 min read

Go pprof를 활용한 성능 프로파일링 가이드

개요

pprof는 Go에 내장된 프로파일링 도구로, CPU 사용량, 메모리 할당, 고루틴 상태 등을 분석할 수 있습니다. 프로덕션 환경에서도 안전하게 사용할 수 있어 성능 최적화에 필수적입니다.

기본 설정

HTTP 서버에 pprof 엔드포인트 추가

package main

import (
    "net/http"
    _ "net/http/pprof" // 자동으로 /debug/pprof/* 엔드포인트 등록
)

func main() {
    go func() {
        // 별도 포트에서 pprof 서버 실행 (보안상 권장)
        http.ListenAndServe("localhost:6060", nil)
    }()
    
    // 메인 애플리케이션 로직
    // ...
}

제공되는 엔드포인트

엔드포인트설명
/debug/pprof/프로파일 인덱스 페이지
/debug/pprof/heap메모리 할당 프로파일
/debug/pprof/goroutine고루틴 스택 트레이스
/debug/pprof/profileCPU 프로파일 (30초)
/debug/pprof/trace실행 트레이스

CPU 프로파일링

프로파일 수집

# 30초간 CPU 프로파일 수집
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30

# 또는 파일로 저장
curl -o cpu.prof http://localhost:6060/debug/pprof/profile?seconds=30
go tool pprof cpu.prof

주요 명령어

# pprof 인터랙티브 모드에서
(pprof) top10          # 상위 10개 함수
(pprof) list funcName  # 특정 함수의 라인별 분석
(pprof) web            # 그래프 시각화 (브라우저)
(pprof) pdf            # PDF로 저장

출력 예시

      flat  flat%   sum%        cum   cum%
     2.50s 25.00% 25.00%      4.00s 40.00%  main.processData
     1.50s 15.00% 40.00%      1.50s 15.00%  runtime.mallocgc
     1.00s 10.00% 50.00%      3.00s 30.00%  encoding/json.Marshal
컬럼설명
flat해당 함수 자체 실행 시간
cum해당 함수 + 호출한 함수 합계 시간

메모리 프로파일링

힙 프로파일 수집

# 현재 힙 상태
go tool pprof http://localhost:6060/debug/pprof/heap

# 할당된 객체 수 기준
go tool pprof -alloc_objects http://localhost:6060/debug/pprof/heap

# 할당된 메모리 크기 기준
go tool pprof -alloc_space http://localhost:6060/debug/pprof/heap

메모리 누수 탐지

// runtime.MemStats 활용
import "runtime"

func printMemStats() {
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    
    fmt.Printf("Alloc = %v MiB\n", m.Alloc / 1024 / 1024)
    fmt.Printf("TotalAlloc = %v MiB\n", m.TotalAlloc / 1024 / 1024)
    fmt.Printf("Sys = %v MiB\n", m.Sys / 1024 / 1024)
    fmt.Printf("NumGC = %v\n", m.NumGC)
}

고루틴 프로파일링

# 현재 고루틴 상태 확인
go tool pprof http://localhost:6060/debug/pprof/goroutine

# 덤프 파일로 저장
curl http://localhost:6060/debug/pprof/goroutine?debug=2 > goroutines.txt

고루틴 누수 징후:

  • 고루틴 수가 지속적으로 증가
  • 특정 함수에서 대기 중인 고루틴이 많음

웹 UI로 시각화

pprof 웹 인터페이스 (Go 1.10+):

go tool pprof -http=:8080 cpu.prof

브라우저에서 http://localhost:8080으로 접속하면:

  • Top: 함수별 CPU/메모리 사용량
  • Graph: 호출 그래프
  • Flame Graph: 플레임 차트
  • Source: 소스 코드 레벨 분석

프로덕션 환경 고도화

1. 보안 설정

package main

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

func main() {
    // 별도 서버에서 인증 추가
    pprofMux := http.NewServeMux()
    pprofMux.HandleFunc("/debug/pprof/", pprof.Index)
    pprofMux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
    pprofMux.HandleFunc("/debug/pprof/profile", pprof.Profile)
    pprofMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
    pprofMux.HandleFunc("/debug/pprof/trace", pprof.Trace)
    
    // 인증 미들웨어 적용
    go http.ListenAndServe("localhost:6060", authMiddleware(pprofMux))
}

2. 연속 프로파일링 (Continuous Profiling)

import (
    "os"
    "runtime/pprof"
    "time"
)

func startContinuousProfiling() {
    ticker := time.NewTicker(10 * time.Minute)
    for range ticker.C {
        f, _ := os.Create(fmt.Sprintf("heap_%s.prof", time.Now().Format("20060102_150405")))
        pprof.WriteHeapProfile(f)
        f.Close()
    }
}

3. 외부 서비스 연동

  • Pyroscope: 오픈소스 연속 프로파일링
  • Datadog Continuous Profiler: 상용 APM
  • Google Cloud Profiler: GCP 통합
// Pyroscope 예시
import "github.com/grafana/pyroscope-go"

func main() {
    pyroscope.Start(pyroscope.Config{
        ApplicationName: "my-app",
        ServerAddress:   "http://pyroscope:4040",
    })
}

벤치마크와 함께 사용

# 벤치마크 실행 + CPU 프로파일
go test -bench=. -cpuprofile=cpu.prof

# 벤치마크 실행 + 메모리 프로파일
go test -bench=. -memprofile=mem.prof

# 분석
go tool pprof cpu.prof

주의사항

  1. 프로덕션 포트 분리: pprof 엔드포인트는 별도 포트에서 실행
  2. 인증 필수: 외부 노출 시 반드시 인증 적용
  3. 오버헤드: CPU 프로파일링은 약 5% 오버헤드 발생
  4. 샘플링 주기: runtime.SetCPUProfileRate()로 조절 가능

참고 자료

Share

Related Articles

Comments

이 블로그는 제가 알고 있는 것들을 잊지 않기 위해 기록하는 공간입니다.
직접 작성한 글도 있고, AI의 도움을 받아 정리한 글도 있습니다.
정확하지 않은 내용이 있을 수 있으니 참고용으로 봐주세요.

© 2026 Seogyu Kim