gRPC 服务集成 pprof
gRPC 虽然底层是基于 HTTP2 协议的,但是 gRPC 服务本身并不提供 HTTP 服务。因为 pprof 是暴露的 HTTP 接口用于性能分析,所以没有办法像 echo 和 gin 这些 HTTP 框架那样可以让 gRPC 和 pprof 监听同一个端口。
从前几篇文章的学习过程中,已经知道了 pprof 做 CPU 分析的原理是 pprof 按照一定的频率采集程序使用 CPU 的情况,确定应用程序在主动消耗 CPU 周期时花费时间的位置。只要 pprof 和 gRPC 服务在同一个进程里面,pprof 即可采集到 gRPC服务的性能样本数据。所以可以在gRPC服务启动时,使用 goroutine 异步启动一个监听其他端口的 HTTP 服务(暴露 pprof 用于样本数据采集的接口)用于 pprof 进行样本数据采集和分析。
下面看一个示例,以 Golang 官方的 helloworld 示例代码为基础,在官方代码基础上集成 pprof :
package main
import (
...
_ "net/http/pprof"
"runtime"
"google.golang.org/grpc"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
)
// ... 略去了部分代码funcmain() {
// 集成 pprof
//
// 对阻塞超过1纳秒的 goroutine 进行数据采集
runtime.SetBlockProfileRate(1)
// 启动一个 http 服务
gofunc() {
http.ListenAndServe(":8000", nil)
}()
//... 略去部分代码
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
log.Printf("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
服务启动后可以通过
localhost:8000/debug/pprof/profile 分析 cpu 使用情况,具体分析方法参考本系列文章的前两篇。
小结
本文主要介绍了 gRPC 服务集成 pprof 的方法。其实 RPC 框架除了 gRPC 外还有很多,业界比较知名的有 thrift、dubbo等,还有很多是可能是自己公司内部自研的。这些 RPC 集成 pprof 的方法和 gRPC 类似,只要 pprof 和 gRPC 服务在同一个进程里面,pprof 就可以进行样本数据采集和分析。下篇文章主要讲解关于 pprof 最佳实践方面的思考。