【问题标题】:How to handle GRPC Golang High CPU Usage如何处理 GRPC Golang 高 CPU 使用率
【发布时间】:2021-12-25 11:39:23
【问题描述】:

我们在使用 grpc 流式传输交易的 golang 函数中存在可疑的高 CPU 使用率。功能很简单,当我们从前端收到ORDER ID数据变化的请求,然后我们消费并流回来。

这里是代码

func (consumer OrderChangesConsumer) Serve(message string) {
    response := messages.OrderChanges{}
    if err := json.Unmarshal([]byte(message), &response); err != nil {
        logData := map[string]interface{}{
            "message": message,
        }
        seelog.Error(commonServices.GenerateLog("parse_message_error", err.Error(), &logData))
    }

    if response.OrderID > 0 {
        services.PublishChanges(response.OrderID, &response)
    }
}




// PublishChanges sends the order change message to the changes channel.
func PublishChanges(orderID int, orderChanges *messages.OrderChanges) {
    orderMutex.RLock()
    defer orderMutex.RUnlock()
    orderChan, ok := orderChans[orderID]
    if !ok {
        return
    }
    orderChan <- orderChanges
}

我们如何改进和测试这个案例的最佳实践?

【问题讨论】:

  • 写信给orderChan的时候,是不是一定要持有锁?如果您在测试ok 之前明确解锁,会更顺利吗?通道写入可能会阻塞,从而使持有锁的代码保持原样。
  • 一些想法:Serve 不是指针接收器方法,因此每次调用时都会复制 OrderChangesConsumer。消息在转换为 []byte 时也会被复制,因此如果消息很大,您将花费大量时间来复制它们。您还应该在进入频道之前解锁您的互斥锁。
  • @jdizzle Go 是复制值的 COW,所以我认为这不会看到复制命中?我还认为编译器在 []byte 到 string 的转换方面更聪明一些,但不太确定。
  • 检查,编译器对字节复制并不那么聪明,这很可能调用 runtime.slicebytetostring,它实际上只是复制字节。我会说,由于在 json 解析中逐字节读取生成的字节切片,因此字节切片副本的性能损失可能远低于 json 解组的开销。

标签: go grpc cpu cpu-usage


【解决方案1】:

将您的 PublishChanges 代码更新为以下内容,看看是否有帮助:

// PublishChanges sends the order change message to the changes channel.
func PublishChanges(orderID int, orderChanges *messages.OrderChanges) {
    orderMutex.RLock()
    orderChan, ok := orderChans[orderID]
    orderMutex.RUnlock()
    if !ok {        
        return
    }
    orderChan <- orderChanges
}

您可能还想考虑使用sync.Map 以获得更易于使用的并发映射。

【讨论】:

  • 所以没有延迟?
  • 正确。频道推送可能需要很长时间并停止 go 例程。如果您持有锁,那么您可能会在锁上造成过多的碰撞,并在睡眠/唤醒时颠簸或在锁上旋转。
  • 如果通道使用 go func() 运行会怎样?喜欢go func() { orderChan &lt;- orderChanges }()
猜你喜欢
  • 1970-01-01
  • 2018-06-18
  • 2014-12-05
  • 2011-05-18
  • 2020-11-22
  • 2018-09-25
  • 2014-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多