19

Go で記述された、ルーティングにGorilla のマルチプレクサを使用する比較的大きな Web アプリケーションがあります。最近、自分の Web アプリケーションが非常に遅いことに気付き、Web アプリケーションのプロファイルを作成したいと考えています。

それについて読んだ後、私が必要としているのはnet/http/pprofのようです。しかし、muxで実行することはできません。最も些細な Web アプリケーションの場合でも。

誰もそれを機能させる方法を知っていますか?

以下は、動作しない単純なコードの例です (つまり、 では何も提供されません/debug)。

package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "math"
    "net/http"
)
import _ "net/http/pprof"

func SayHello(w http.ResponseWriter, r *http.Request) {
    for i := 0; i < 1000000; i++ {
        math.Pow(36, 89)
    }
    fmt.Fprint(w, "Hello!")
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/hello", SayHello)
    http.ListenAndServe(":6060", r)
}
4

8 に答える 8

33

これに対する私の好ましい方法は、net/http/pprof自分自身を に登録させてから、以下http.DefaultServeMuxで始まるすべてのリクエストを渡すこと/debug/pprof/です。

package main

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

    "github.com/gorilla/mux"
)

func main() {
    router := mux.NewRouter()
    router.PathPrefix("/debug/pprof/").Handler(http.DefaultServeMux)
    if err := http.ListenAndServe(":6060", router); err != nil {
        panic(err)
    }
}

このアプローチは、非表示の初期化メソッドの実装に依存するアプローチよりもはるかに安定しており、何も見逃していないことも保証されます。

于 2015-10-20T16:08:46.067 に答える
31

user983716 - ご質問と解決策をありがとうございます!

次のように、ソリューションに数行を追加するまで、Web インデックス ( http://[my-server]/debug/pprof ) からのリンクを使用できませんでした。

...

func AttachProfiler(router *mux.Router) {
    router.HandleFunc("/debug/pprof/", pprof.Index)
    router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
    router.HandleFunc("/debug/pprof/profile", pprof.Profile)
    router.HandleFunc("/debug/pprof/symbol", pprof.Symbol)

    // Manually add support for paths linked to by index page at /debug/pprof/
    router.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine"))
    router.Handle("/debug/pprof/heap", pprof.Handler("heap"))
    router.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate"))
    router.Handle("/debug/pprof/block", pprof.Handler("block"))
}

...

誰かが同じ問題を抱えている場合、これが役立つことを願っています!

于 2015-05-12T21:17:33.220 に答える
13

その質問を申し訳ありません。答えはpprofの init() 関数にあります。pprof4 つの機能をマルチプレクサ ルータに追加するだけです。上記の固定コードは次のとおりです。

package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "math"

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

func AttachProfiler(router *mux.Router) {
    router.HandleFunc("/debug/pprof/", pprof.Index)
    router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
    router.HandleFunc("/debug/pprof/profile", pprof.Profile)
    router.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
}

func SayHello(w http.ResponseWriter, r *http.Request) {
    for i := 0; i < 1000000; i++ {
        math.Pow(36, 89)
    }
    fmt.Fprint(w, "Hello!")
}

func main() {
    r := mux.NewRouter()
    AttachProfiler(r)
    r.HandleFunc("/hello", SayHello)
    http.ListenAndServe(":6060", r)
}
于 2013-10-25T13:35:22.010 に答える
4

私は別のことをしました。別のポートに別のネイティブhttpサーバーを追加しましたが、そのままで動作します

package main

import (
    "fmt"
    "log"
    "net/http"

    _ "net/http/pprof"
)


func main() {
    go func() {
        log.Println(http.ListenAndServe(":6060", nil))
    }()
    log.Fatalln(http.ListenAndServe(":8080", route.Handlers()))
}

現在、pprof エンドポイントは http://localhost:6060/debug/pprof/にあり、アプリケーションはポート :8080 で実行されています。

于 2015-11-30T14:09:25.653 に答える
1

ちょうどそう:

r := mux.NewRouter()
r.PathPrefix("/debug").Handler(http.DefaultServeMux)
于 2016-08-09T07:16:01.717 に答える