【问题标题】:How to manage memory efficiently with Async GRPC calls如何使用异步 GRPC 调用有效地管理内存
【发布时间】:2021-08-08 06:36:14
【问题描述】:

我们在使用 GRPC 来“触发并忘记”消息时遇到了内存问题。

我们有一个管理数据库请求的服务 A 和一个将事件数据发布到外部数据源的服务 B。

这两个服务都实现了 GRPC 服务来与它们通信。例如服务 B 有一个定义:

service MessageBusService {
    rpc PublishRevision (RevisionRequest) returns (EmptyResponse) {}
}
message EmptyResponse{
}

在服务 A 中,我们可能会进行数千次调用以“触发并忘记”异步服务调用。

_ = grpcClient.PublishRevisionAsync(revision);

“修订”对象的大小约为 1MB。在执行内存分析时,我们注意到该服务的内存消耗可以达到 600MB 以上。这似乎是因为我们分拆的任务将保留内存中的对象,直到 GRPC 服务响应“EmptyResponse”对象。

有谁知道 GRPC 是否支持任何方式来真正“触发并忘记”服务,或者是否有办法托管明确不发送响应的服务?

有没有更好的方法来执行这项任务?

任何帮助将不胜感激。

【问题讨论】:

    标签: c# multithreading memory-management concurrency grpc


    【解决方案1】:

    以防其他人遇到此问题并需要解决方案。好的,经过一番研究,我想出了一种 hacky 方法来做我想做的事。

    service MessageBusService {
        rpc PublishRevision (stream RevisionRequest) returns (EmptyResponse) {}
    }
    message EmptyResponse{
    }
    
    

    您可以通过将每个元素写入流中来“触发并忘记”到 GRPC 端点,因为您不会收到每次写入流的响应。

    微软页面https://docs.microsoft.com/en-us/dotnet/architecture/grpc-for-wcf-developers/rpc-types上有一些过时的例子

    【讨论】:

    • 您是否尝试过 gRPC 支持的流式传输选项之一,它使发送方无需等待接收方的响应就可以发送尽可能多的消息(只要流控制支持)?
    猜你喜欢
    • 2014-06-16
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    • 2019-08-07
    • 1970-01-01
    • 2013-12-07
    相关资源
    最近更新 更多