了解golang分析输出

n3h0vuf2  于 2021-06-07  发布在  Kafka
关注(0)|答案(0)|浏览(268)

一些背景:
我正在调试一个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
    }
}


谢谢,

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题