一些背景:
我正在调试一个gogrpc服务器,一个特定的api调用似乎要花费很多时间。这个电话对Kafka读了很多遍(比如说10-20遍),所以我认为这需要一些时间,只是没有那么多时间。
一个api调用大约需要1-3秒才能完成,但是如果我在一个脚本中进行40个api调用,那么完成所有调用几乎需要30秒。但它并没有像我预期的那样“同时”完成它们,第一个需要5秒钟,而后面的每秒钟大约会吐出1个。
它需要29秒,一次响应所有40个请求。当请求花费的时间太长时,会导致api调用程序超时。
我试着分析一下cpu,看看我在哪里花时间。但我对这一点还不熟悉,而且go profiler的输出没有什么意义。
我已经用 go tool pprof
,但在解释输出时遇到一些问题。
cpu调用图
有一个描述时间、类型、buildid等的框 Duration
在这个框中,这是描述cpu运行的总时间吗?不包括wiat时间
有两种类型的边,实线和虚线。有什么区别?边缘上的时间是什么意思?
箭头的方向是否意味着呼叫方向?e、 函数a调用b,在图上它将是a->b?
每个顶点底部都有一个时间,例如0.49秒(45.79%)中的0.01秒(0.93%),这个时间是什么意思?
块纵断面
与上面的#4相同,边和顶点上都有时间。这是什么意思?
编辑:
我的服务器做的是从Kafka流中检索一些数据。我已经确定了什么是缓慢的,我已经写了一个脚本,只有Kafka调用函数。下面是脚本和块分析图。
kafka的每次消耗大约需要50-100ms,但由于大部分时间都花在io上,我预计api的吞吐量实际上相当高,而事实并非如此。如果我打100个电话,大约需要3秒,如果我打400个,大约需要10秒。试着看看如何提高api的吞吐量
func main() {
f, _ := os.Create("cpu.prof")
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
block, _ := os.Create("block.prof")
runtime.SetBlockProfileRate(1)
p := pprof.Lookup("block")
defer p.WriteTo(block, 0)
var wg sync.WaitGroup
wg.Add(messageCount)
for i := 0; i < messageCount; i++ {
go func() {
// consume()
withConsumer()
wg.Done()
}()
}
wg.Wait()
}
var servers = []string{"kafka-1", "kafka-2", "kafka-3"}
var count = 0
var partition = int32(0)
func consume() {
index := count
t := time.Now()
count++
fmt.Println("starting consume", index)
defer func() {
fmt.Println("consume ", index, "took", time.Since(t).String())
}()
consumer, err := sarama.NewConsumer(servers, nil)
if err != nil {
panic(err)
}
var max, min int64
max = 1431401
min = 2
defer func() {
consumer.Close()
}()
pc, err := consumer.ConsumePartition("source-topic", partition, rand.Int63n(max-min)+min)
if err != nil {
panic(err)
}
defer func() {
pc.Close()
}()
signals := make(chan os.Signal, 1)
signal.Notify(signals, os.Interrupt)
select {
case msg := <-pc.Messages():
fmt.Println("msg: ", len(msg.Value))
case <-signals:
return
}
}
谢谢,
暂无答案!
目前还没有任何答案,快来回答吧!