在 go lang 中分析 http 处理程序
profiling http handler in go lang
我正在尝试分析我用 go 编写的 http 处理程序。在每个 http 请求上从 S3 下载图像,调整大小 it/crop 并将其写入响应。
我已遵循此 link 并尝试使用简单方法和困难方法来分析我的代码。现在,当我使用代码中提到的以下行时。
defer profile.Start(profile.CPUProfile).Stop()
它没有在 /tmp/profie[some number]/cpu.pprof
文件中写入任何内容
func main() {
defer profile.Start(profile.CPUProfile).Stop()
if err := http.ListenAndServe(":8081", http.HandlerFunc(serveHTTP)); err != nil {
logFatal("Error when starting or running http server: %v", err)
}
}
func serveHTTP(w http.ResponseWriter, r *http.Request) {
keyName := r.URL.Path[1:]
s3Client := s3.New(session.New(), &aws.Config{Region: aws.String(region)})
params := &s3.GetObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(keyName),
}
mw := imagick.NewMagickWand()
defer mw.Destroy()
...
}
此外,当我在 serveHTTP
中使用 defer profile.Start(profile.CPUProfile).Stop()
行时,例如:
func serveHTTP(w http.ResponseWriter, r *http.Request) {
defer profile.Start(profile.CPUProfile).Stop()
......
}
它在 /tmp/profile[some number]
文件夹中创建了多个文件。所以,第一个问题是为什么它不写入文件,其次它不应该放在 serveHTTP method
内,因为服务器只会启动一次。因此 main()
将被调用一次,而 serveHTTP
将在每次请求时被调用。
第 1 部分
. 124: s3Client := s3.New(session.New(), &aws.Config{Region: aws.String(region)})
. . 125: params := &s3.GetObjectInput{
. . 126: Bucket: aws.String(masterBucketName),
. . 127: Key: aws.String(keyName),
. 32.01kB 128: }
. . 129:
. . 130: mw := imagick.NewMagickWand()
. . 131: defer mw.Destroy()
. . 132:
. . 133: out, err := s3Client.GetObject(params)
. . 134:
. . 135: if strings.EqualFold(keyName[strings.LastIndex(keyName,".")+1:len(keyName)], "gif") {
. . 136:
. 40.11kB 137: blobGiff, err := ioutil.ReadAll(out.Body)
. . 138: w.Header().Set("Content-Type", "image/gif")
. . 139: w.Header().Set("Cache-Control", "max-age: 604800, public")
. . 140: w.Header().Set("Last-Modified", time.Now().Format(http.TimeFormat))
. . 141: w.Header().Set("Expires", time.Now().AddDate(1, 0, 0).Format(http.TimeFormat))
. . 142:
第 2 部分:
else {
. . 167: img, err := ioutil.ReadAll(out.Body)
. . 168: if err != nil {
. . 169:
. . 170: w.WriteHeader(http.StatusNotFound)
. 1.56MB 171: return
. . 172: }
另外,上面两部分128、137、171行有内存泄漏,对吧?此外,我没有找到 close/destroy s3Client
和 blobGiff
(字节 [])的任何选项。
要在 运行 时分析 http 服务器,您可以使用 net/http/pprof
包。
只需添加
import _ "net/http/pprof"
导入并在浏览器中打开 http://localhost:8081/debug/pprof/
。
首先使用import "net/http/pprof"
NOT import _ "net/http/pprof。后来有人没认出下面路由中的pprof
.
我使用的是默认值 serveMux/multiplexer。但后来我创建了自己的,因为人们认为它具有性能影响。
myMux := http.NewServeMux()
然后添加请求的路由
myMux.HandleFunc("/", serveHTTP)
此外,我还添加了使 http://localhost:8081/debug/pprof/
工作的路由
myMux.HandleFunc("/debug/pprof/", pprof.Index)
myMux.HandleFunc("/debug/pprof/{action}", pprof.Index)
myMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
因此,最终代码将是:
导入“net/http/pprof
func main() {
myMux := http.NewServeMux()
myMux.HandleFunc("/", serveHTTP)
myMux.HandleFunc("/debug/pprof/", pprof.Index)
myMux.HandleFunc("/debug/pprof/{action}", pprof.Index)
myMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
if err := http.ListenAndServe(":8081", myMux); err != nil {
logFatal("Error when starting or running http server: %v", err)
}
}
我正在尝试分析我用 go 编写的 http 处理程序。在每个 http 请求上从 S3 下载图像,调整大小 it/crop 并将其写入响应。
我已遵循此 link 并尝试使用简单方法和困难方法来分析我的代码。现在,当我使用代码中提到的以下行时。
defer profile.Start(profile.CPUProfile).Stop()
它没有在 /tmp/profie[some number]/cpu.pprof
文件中写入任何内容
func main() {
defer profile.Start(profile.CPUProfile).Stop()
if err := http.ListenAndServe(":8081", http.HandlerFunc(serveHTTP)); err != nil {
logFatal("Error when starting or running http server: %v", err)
}
}
func serveHTTP(w http.ResponseWriter, r *http.Request) {
keyName := r.URL.Path[1:]
s3Client := s3.New(session.New(), &aws.Config{Region: aws.String(region)})
params := &s3.GetObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(keyName),
}
mw := imagick.NewMagickWand()
defer mw.Destroy()
...
}
此外,当我在 serveHTTP
中使用 defer profile.Start(profile.CPUProfile).Stop()
行时,例如:
func serveHTTP(w http.ResponseWriter, r *http.Request) {
defer profile.Start(profile.CPUProfile).Stop()
......
}
它在 /tmp/profile[some number]
文件夹中创建了多个文件。所以,第一个问题是为什么它不写入文件,其次它不应该放在 serveHTTP method
内,因为服务器只会启动一次。因此 main()
将被调用一次,而 serveHTTP
将在每次请求时被调用。
第 1 部分
. 124: s3Client := s3.New(session.New(), &aws.Config{Region: aws.String(region)})
. . 125: params := &s3.GetObjectInput{
. . 126: Bucket: aws.String(masterBucketName),
. . 127: Key: aws.String(keyName),
. 32.01kB 128: }
. . 129:
. . 130: mw := imagick.NewMagickWand()
. . 131: defer mw.Destroy()
. . 132:
. . 133: out, err := s3Client.GetObject(params)
. . 134:
. . 135: if strings.EqualFold(keyName[strings.LastIndex(keyName,".")+1:len(keyName)], "gif") {
. . 136:
. 40.11kB 137: blobGiff, err := ioutil.ReadAll(out.Body)
. . 138: w.Header().Set("Content-Type", "image/gif")
. . 139: w.Header().Set("Cache-Control", "max-age: 604800, public")
. . 140: w.Header().Set("Last-Modified", time.Now().Format(http.TimeFormat))
. . 141: w.Header().Set("Expires", time.Now().AddDate(1, 0, 0).Format(http.TimeFormat))
. . 142:
第 2 部分:
else {
. . 167: img, err := ioutil.ReadAll(out.Body)
. . 168: if err != nil {
. . 169:
. . 170: w.WriteHeader(http.StatusNotFound)
. 1.56MB 171: return
. . 172: }
另外,上面两部分128、137、171行有内存泄漏,对吧?此外,我没有找到 close/destroy s3Client
和 blobGiff
(字节 [])的任何选项。
要在 运行 时分析 http 服务器,您可以使用 net/http/pprof
包。
只需添加
import _ "net/http/pprof"
导入并在浏览器中打开 http://localhost:8081/debug/pprof/
。
首先使用import "net/http/pprof"
NOT import _ "net/http/pprof。后来有人没认出下面路由中的pprof
.
我使用的是默认值 serveMux/multiplexer。但后来我创建了自己的,因为人们认为它具有性能影响。
myMux := http.NewServeMux()
然后添加请求的路由
myMux.HandleFunc("/", serveHTTP)
此外,我还添加了使 http://localhost:8081/debug/pprof/
工作的路由
myMux.HandleFunc("/debug/pprof/", pprof.Index)
myMux.HandleFunc("/debug/pprof/{action}", pprof.Index)
myMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
因此,最终代码将是:
导入“net/http/pprof
func main() {
myMux := http.NewServeMux()
myMux.HandleFunc("/", serveHTTP)
myMux.HandleFunc("/debug/pprof/", pprof.Index)
myMux.HandleFunc("/debug/pprof/{action}", pprof.Index)
myMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
if err := http.ListenAndServe(":8081", myMux); err != nil {
logFatal("Error when starting or running http server: %v", err)
}
}