pprof是golang提供的性能分析工具,這里就不過多介紹了。
使用方式很簡單,導(dǎo)入pprof包即可
import _ "net/http/pprof"
pprof.go源文件init函數(shù)會初始化性能監(jiān)控接口
func init() {
http.HandleFunc("/debug/pprof/", Index)
http.HandleFunc("/debug/pprof/cmdline", Cmdline)
http.HandleFunc("/debug/pprof/profile", Profile)
http.HandleFunc("/debug/pprof/symbol", Symbol)
http.HandleFunc("/debug/pprof/trace", Trace)
}
但是這種簡單的方式使用會導(dǎo)致一個大問題,就是/debug/pprof接口會隨著我們的應(yīng)用暴露到公網(wǎng)
1. net/http
可通過http多路復(fù)用將pprof接口和業(yè)務(wù)接口隔離
業(yè)務(wù)接口使用8080端口,pprof接口使用內(nèi)網(wǎng)的8081端口
package main
import (
"fmt"
"log"
"net/http"
_ "net/http/pprof"
)
func main() {
go func() {
//內(nèi)網(wǎng)可訪問的pprof地址
log.Fatal(http.ListenAndServe("127.0.0.1:8081", nil))
}()
mux := http.NewServeMux()
mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
fmt.Fprintf(writer, "hello")
})
//外網(wǎng)可訪問的接口地址
log.Fatal(http.ListenAndServe(":8080", mux))
}
2. gin
如果使用gin框架,可通過gin-contrib/pprof包實現(xiàn)隔離/認(rèn)證
import "github.com/gin-contrib/pprof"
package main
import (
"encoding/base64"
"fmt"
"github.com/gin-contrib/pprof"
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
//自定義路由
//pprof.Register(router,"dev/pprof")
//注冊默認(rèn)路由 /debug/pprof
//pprof.Register(router)
//注冊組,需要認(rèn)證
authStr := fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte("admin:123456")))
pprofGroup := router.Group("/admin", func(c *gin.Context) {
auth := c.Request.Header.Get("Authorization")
if auth != authStr {
c.Header("www-Authenticate", "Basic")
c.AbortWithStatus(http.StatusUnauthorized)
return
}
c.Next()
})
pprof.RouteRegister(pprofGroup, "pprof")
router.Run(":8080")
}
將pprof接口注冊到admin路由組,如果賬號密碼錯誤響應(yīng)頭設(shè)置www-Authenticate: Basic,表示使用http基本認(rèn)證(彈出登錄框),并返回狀態(tài)碼401(未授權(quán))
http基本認(rèn)證會將(賬號+冒號+密碼)Base64后并添加Basic標(biāo)識
如賬號密碼為admin/123456
base64(admin:123456) = YWRtaW46MTIzNDU2
最后請求頭會添加
Authorization: Basic YWRtaW46MTIzNDU2
訪問http://localhost:8080/admin/pprof/
后會彈出登錄框,輸入賬號密碼 admin/123456后就能訪問pprof界面了