stream - 多个一元 rpc 调用与 grpc 中长时间运行的双向流式传输?
问题描述
我有一个用例,其中许多客户端需要不断向服务器发送大量指标(几乎是永久的)。服务器需要存储这些事件,并在以后处理它们。我不希望服务器对这些事件做出任何响应。
我正在考虑为此使用grpc。最初,我认为客户端流式传输可以(就像 envoy 所做的那样),但问题是客户端流式传输无法确保应用程序级别的可靠交付(即,如果流在两者之间关闭,则实际处理了多少消息发送由服务器),我买不起这个。
我的思考过程是,我应该使用双向流,在服务器流中使用 acks,或者使用多个一元 rpc 调用(可能在重复字段中对事件进行一些批处理以提高性能)。
其中哪一个会更好?
解决方案
问题是客户端流无法确保应用程序级别的可靠传递(即,如果流在两者之间关闭,发送的消息有多少是由服务器实际处理的),我负担不起
这意味着您需要回应。即使响应只是一个确认,从 gRPC 的角度来看,它仍然是一个响应。
一般方法应该是“使用一元”,除非可以通过流解决足够大的问题以克服其复杂性成本。我在 2018 CloudNativeCon NA 上讨论了这个问题(视频有幻灯片和 YouTube 的链接)。
例如,如果您有多个后端,那么每个一元 RPC 可能会被发送到不同的后端。这可能会导致各种后端同步自身的高开销。流式 RPC 在开始时选择一个后端并继续使用相同的后端。因此流式传输可能会降低后端同步的频率,并在服务实现中实现更高的性能。但是当错误发生时,流式传输会增加复杂性,在这种情况下,它会导致 RPC 变得长寿,这使得负载平衡更加复杂。因此,您需要权衡流式传输/长寿命 RPC 所增加的复杂性是否为您的应用程序提供了足够大的好处。
我们通常不建议使用流式 RPC 来获得更高的 gRPC 性能。确实,在流上发送消息比新的一元 RPC 更快,但改进是固定的并且具有更高的复杂性。相反,当它可以提供更高的应用程序(您的代码)性能或更低的应用程序复杂性时,我们建议使用流式 RPC。
推荐阅读
- ios - 无法访问对象数据,只能在 Swift/Xcode 的调试器中显示
- c++ - 如何使用 operator>> 在自定义字符串中输入多个单词?
- dynamic-programming - 这个问题的 dp 和转换是什么
- c++ - 将 C++ 解决方案导出为 .lib 文件并将其用于另一个项目
- c# - 如何参考 ctor 重载文档
? - c# - 无法从 IConfigurationRoot .NET Core 控制台应用程序获取节数据
- javascript - 如何将组件延迟加载到 React 路由器 dom Route 组件?
- javascript - 为一个对象设置多个值
- tensorflow - 如何使用 Gammatone 过滤器(或任何过滤器)初始化 CNN 层以进行声音回归(或分类)?
- python - 用于网络抓取的可见和搜索 URL