如何使用异步 GRPC 调用有效地管理内存

Posted

技术标签:

【中文标题】如何使用异步 GRPC 调用有效地管理内存【英文标题】:How to manage memory efficiently with Async GRPC calls 【发布时间】: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 是否支持任何方式来真正“触发并忘记”服务,或者是否有办法托管明确不发送响应的服务?

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

任何帮助将不胜感激。

【问题讨论】:

【参考方案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 支持的流式传输选项之一,它使发送方无需等待接收方的响应就可以发送尽可能多的消息(只要流控制支持)?

以上是关于如何使用异步 GRPC 调用有效地管理内存的主要内容,如果未能解决你的问题,请参考以下文章

如何以异步方式有效地将变量从 Matlab 传递到 GPU?

如何正确异步使用grpc(ClientAsyncReaderWriter)

Abp + Grpc 如何实现用户会话状态传递

有效地扫描进程的内存

如何在google colab中有效地使用内存?

如何防止在 dart 中使用 expectAsync 的单元测试进展?