Herkese merhaba!

Uzun yıllardır bol miktarda kişisel zaman ve enerji harcayarak bilgimizi hepinizle paylaşıyoruz. Ancak şu andan itibaren bu blogu çalışır durumda tutabilmek için yardımınıza ihtiyacımız var. Yapmanız gereken tek şey, sitedeki reklamlardan birine tıklamak olacaktır, aksi takdirde hosting vb. masraflar nedeniyle maalesef yayından kaldırılacaktır. Teşekkürler.

Bu örnekte, uygulama performansı verilerini toplamak ve görselleştirmek için Golang'ın pprof paketini nasıl kullanabileceğinizi göstereceğim. Bulgular darboğazları tanımlamak ve genel performansı iyileştirmek için kullanılabilir. Hangi kod satırının ne kadar çalıştığını bile görebilirsiniz. Demek istediğim, satır satır performans analizi! Ben şahsen kendi API'lerimin performanslarını %60 oranında artırmayı başardım. High Performance Go Workshop başlığı altındaki çok değerli olan yazıyı da okumanızı tavsiye ederim.


Kurulum


Tam kurulum bilgileri burada bulunabilir ama sadece go get -u github.com/google/pprof komutu ile de kurulumu yapabilirsiniz.


Uygulama


Elimizde aşağıdakine benzer basit bir HTTP API olduğunu varsayıyorum.


Path: /Users/inanzzz/Language/Go/src/github.com/inanzzz/game
Binary: /Users/inanzzz/Language/Go/src/github.com/inanzzz/game/bin/game
Server: http://0.0.0.0:8000

URL adresleri


HTTP sunucunuzun yönlendiricisine aşağıdaki yolları ekleyin. Bu adreslerin ne yaptığını görmek için ana pprof.go dosyasını açabilirsiniz.


// router := github.com/julienschmidt/httprouter
router.HandlerFunc(http.MethodGet, "/debug/pprof/", pprof.Index)
router.HandlerFunc(http.MethodGet, "/debug/pprof/allocs", pprof.Index)
router.HandlerFunc(http.MethodGet, "/debug/pprof/goroutine", pprof.Index)
router.HandlerFunc(http.MethodGet, "/debug/pprof/heap", pprof.Index)
router.HandlerFunc(http.MethodGet, "/debug/pprof/profile", pprof.Profile)
router.HandlerFunc(http.MethodGet, "/debug/pprof/trace", pprof.Trace)
router.HandlerFunc(http.MethodGet, "/debug/pprof/symbol", pprof.Symbol)

_ "net/http/pprof" paketini ekleyin. Bu kadar! Veri toplama ve görselleştirme işlemine başlayabiliriz.


Veri oluşturma ve toplama


Adreslerinizden birine sürekli olarak birçok istek göndermeniz gerekir, böylece pprof veri toplayabilir, aksi takdirde uygulama hızlı bir şekilde sonlanır ve veri toplamak için zamanınız olmaz. Ben bunun için bir k6 komut dosyası kullanıyorum, ancak isterseniz bir döngüde cURL komutunu kullanabilirsiniz. Ben 10 saniye boyunca GET http://0.0.0.0:8000/home adresine aynı anda 100'er istek göndereceğim.


Biraz istek gönderelim ve CPU verilerini toplayalım. Pprof komutunu çalıştırır çalıştırmaz, hızlı bir şekilde istek komut dosyanızı (veya tam tersi) çalıştırmalısınız!


İstek gönderme


$ k6 run scripts/k6/home.js

Veri toplama


Bu biraz çalışacak, o nedenle biraz sabırlı olun.


$ go tool pprof /Users/inanzzz/Language/Go/src/github.com/inanzzz/game/bin/game http://0.0.0.0:8000/debug/pprof/profile

// Result
Fetching profile over HTTP from http://0.0.0.0:8000/debug/pprof/profile
Saved profile in /Users/inanzzz/pprof/pprof.game.samples.cpu.018.pb.gz
File: game
Type: cpu
Time: Dec 28, 2019 at 2:15pm (GMT)
Duration: 30.01s, Total samples = 0
No samples were found with the default sample value type.
Try "sample_index" command to analyze different sample values.
Entering interactive mode (type "help" for commands, "o" for options)

Verileri görselleştirme


Bu komut, grafikleri görmeniz için tarayıcınızda http://localhost:8080/ui/ adresini açar.


$ go tool pprof -http=:8080 /Users/inanzzz/pprof/pprof.game.samples.cpu.017.pb.gz

Bu komut sadece "trace" diyagramı için veri üretimi ve görselleştirmeye yarar.


// Generate data.
$ wget http://0.0.0.0:8000/debug/pprof/trace?seconds=10 -O tracing

// Serve on the browser.
$ go tool trace tracing
2019/12/28 14:43:20 Parsing trace...
2019/12/28 14:43:21 Splitting trace...
2019/12/28 14:43:22 Opening browser. Trace viewer is listening on http://127.0.0.1:64056