某些背景信息:
我正在尝试调试GoGRPC服务器,特定的API调用似乎需要花费很多时间。这个调用会对Kafka进行一些读取(比方说10-20),所以我预计它需要一些时间,而不是那么多。
1 API调用大约需要1-3秒才能完成,但如果我在脚本中进行40次api调用,则需要将近30秒才能完成所有调用。但它并没有像我预期的那样“同时”完成它们,第一个需要花费5秒钟,而后来每秒花费1秒左右。
需要29秒才能同时响应所有40个请求。这会导致API调用者在请求耗时太长时超时。
我正试图分析CPU,看看我花时间在哪里。但我是新手,并且go profiler的输出没有多大意义。
我使用go tool pprof
生成了图表,但在解释输出方面遇到了一些麻烦。
CPU调用图
Duration
是描述CPU运行的总时间的?不包括wiat时间阻止个人资料
编辑:
我的服务器所做的是从kafka流中检索一些数据。我已经确定了什么是慢的,我写了一个只有kafka调用函数的脚本。这是脚本和块分析图。
对pafka的每次消耗大约需要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
}
}
答案 0 :(得分:0)
正确。 https://golang.org/doc/diagnostics#profiling 说:
<块引用>cpu:CPU 配置文件决定程序在何处花费时间 主动消耗 CPU 周期(与睡眠或等待时相反) 用于 I/O)。
<块引用>https://github.com/google/pprof/issues/493 表示“点/虚线表示中间节点已被删除。删除节点是为了使图形足够小以进行可视化。”
https://gperftools.github.io/gperftools/cpuprofile.html 表示“每条边都标有被调用者代表调用者花费的时间。”
<块引用>是的。
<块引用>第一次是当地时间。第二次是累计时间。 https://gperftools.github.io/gperftools/cpuprofile.html 详细说明:
<块引用>“本地”时间是直接执行指令所花费的时间 包含在程序中(以及任何其他程序中 内联到程序中)。 “累计”时间是 “本地”时间和在任何被调用者中花费的时间。如果累计时间 与当地时间相同,不打印。