如何使用异步 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?