1
0
mirror of https://github.com/go-micro/go-micro.git synced 2025-05-13 21:16:43 +02:00

fixing mem.pprof issue: (#2198)

parsing profile: concatenated profiles detected
fixing web service not start profile issue
fixing no default profile options issue
This commit is contained in:
Johnson C 2021-08-04 16:39:01 +08:00 committed by GitHub
parent c3107e6843
commit 3e0411a3f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 40 deletions

View File

@ -12,6 +12,8 @@ import (
"github.com/asim/go-micro/v3/client" "github.com/asim/go-micro/v3/client"
"github.com/asim/go-micro/v3/config" "github.com/asim/go-micro/v3/config"
"github.com/asim/go-micro/v3/debug/profile" "github.com/asim/go-micro/v3/debug/profile"
"github.com/asim/go-micro/v3/debug/profile/http"
"github.com/asim/go-micro/v3/debug/profile/pprof"
"github.com/asim/go-micro/v3/debug/trace" "github.com/asim/go-micro/v3/debug/trace"
"github.com/asim/go-micro/v3/logger" "github.com/asim/go-micro/v3/logger"
"github.com/asim/go-micro/v3/registry" "github.com/asim/go-micro/v3/registry"
@ -257,7 +259,10 @@ var (
DefaultAuths = map[string]func(...auth.Option) auth.Auth{} DefaultAuths = map[string]func(...auth.Option) auth.Auth{}
DefaultProfiles = map[string]func(...profile.Option) profile.Profile{} DefaultProfiles = map[string]func(...profile.Option) profile.Profile{
"http": http.NewProfile,
"pprof": pprof.NewProfile,
}
DefaultConfigs = map[string]func(...config.Option) (config.Config, error){} DefaultConfigs = map[string]func(...config.Option) (config.Config, error){}
) )

View File

@ -7,7 +7,6 @@ import (
"runtime" "runtime"
"runtime/pprof" "runtime/pprof"
"sync" "sync"
"time"
"github.com/asim/go-micro/v3/debug/profile" "github.com/asim/go-micro/v3/debug/profile"
) )
@ -17,7 +16,6 @@ type profiler struct {
sync.Mutex sync.Mutex
running bool running bool
exit chan bool
// where the cpu profile is written // where the cpu profile is written
cpuFile *os.File cpuFile *os.File
@ -25,23 +23,6 @@ type profiler struct {
memFile *os.File memFile *os.File
} }
func (p *profiler) writeHeap(f *os.File) {
defer f.Close()
t := time.NewTicker(time.Second * 30)
defer t.Stop()
for {
select {
case <-t.C:
runtime.GC()
pprof.WriteHeapProfile(f)
case <-p.exit:
return
}
}
}
func (p *profiler) Start() error { func (p *profiler) Start() error {
p.Lock() p.Lock()
defer p.Unlock() defer p.Unlock()
@ -50,15 +31,12 @@ func (p *profiler) Start() error {
return nil return nil
} }
// create exit channel cpuFile := filepath.Join(os.TempDir(), "cpu.pprof")
p.exit = make(chan bool) memFile := filepath.Join(os.TempDir(), "mem.pprof")
cpuFile := filepath.Join("/tmp", "cpu.pprof")
memFile := filepath.Join("/tmp", "mem.pprof")
if len(p.opts.Name) > 0 { if len(p.opts.Name) > 0 {
cpuFile = filepath.Join("/tmp", p.opts.Name+".cpu.pprof") cpuFile = filepath.Join(os.TempDir(), p.opts.Name+".cpu.pprof")
memFile = filepath.Join("/tmp", p.opts.Name+".mem.pprof") memFile = filepath.Join(os.TempDir(), p.opts.Name+".mem.pprof")
} }
f1, err := os.Create(cpuFile) f1, err := os.Create(cpuFile)
@ -76,9 +54,6 @@ func (p *profiler) Start() error {
return err return err
} }
// write the heap periodically
go p.writeHeap(f2)
// set cpu file // set cpu file
p.cpuFile = f1 p.cpuFile = f1
// set mem file // set mem file
@ -93,19 +68,20 @@ func (p *profiler) Stop() error {
p.Lock() p.Lock()
defer p.Unlock() defer p.Unlock()
select { if !p.running {
case <-p.exit:
return nil return nil
default: }
close(p.exit)
pprof.StopCPUProfile() pprof.StopCPUProfile()
p.cpuFile.Close() p.cpuFile.Close()
runtime.GC()
pprof.WriteHeapProfile(p.memFile)
p.memFile.Close()
p.running = false p.running = false
p.cpuFile = nil p.cpuFile = nil
p.memFile = nil p.memFile = nil
return nil return nil
} }
}
func (p *profiler) String() string { func (p *profiler) String() string {
return "pprof" return "pprof"

View File

@ -8,6 +8,7 @@ import (
"os" "os"
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"runtime"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -445,6 +446,23 @@ func (s *service) Run() error {
return err return err
} }
// start the profiler
if s.opts.Service.Options().Profile != nil {
// to view mutex contention
runtime.SetMutexProfileFraction(5)
// to view blocking profile
runtime.SetBlockProfileRate(1)
if err := s.opts.Service.Options().Profile.Start(); err != nil {
return err
}
defer func() {
if err := s.opts.Service.Options().Profile.Stop(); err != nil {
logger.Error(err)
}
}()
}
if err := s.register(); err != nil { if err := s.register(); err != nil {
return err return err
} }