avm*_*han 15 stream grpc grpc-java
我有一个用例,其中许多客户端需要不断向服务器发送大量指标(几乎是永久的)。服务器需要存储这些事件,并在以后处理它们。我不希望服务器对这些事件有任何响应。
我正在考虑为此使用grpc。最初,我认为客户端流可以做(就像 envoy 那样),但问题是客户端流不能确保在应用程序级别的可靠交付(即,如果流在两者之间关闭,则实际处理了多少发送的消息由服务器),我负担不起。
我的思考过程是,我应该使用双向流、服务器流中的 acks 或多个一元 rpc 调用(可能在重复字段中对事件进行一些批处理以提高性能)。
这些哪个会更好?
Eri*_*son 24
问题是客户端流无法确保应用程序级别的可靠交付(即,如果流在两者之间关闭,则服务器实际处理了发送的多少消息),我负担不起
这意味着您需要回应。即使响应只是一个确认,从 gRPC 的角度来看,它仍然是一个响应。
一般方法应该是“使用一元”,除非可以通过流解决足够大的问题以克服其复杂性成本。我在 2018 CloudNativeCon NA 上讨论了这个问题(视频有幻灯片和 YouTube 的链接)。
例如,如果您有多个后端,那么每个一元 RPC 可能会发送到不同的后端。这可能会导致这些各种后端同步自身的高开销。流式 RPC 在开始时选择一个后端并继续使用相同的后端。因此,流式传输可能会降低后端同步的频率,并在服务实现中实现更高的性能。但是当发生错误时,流式传输会增加复杂性,在这种情况下,它会导致 RPC 变得长期存在,从而使负载平衡变得更加复杂。因此,您需要权衡流/长寿命 RPC 增加的复杂性是否为您的应用程序提供了足够大的好处。
我们通常不建议使用流式 RPC 来获得更高的 gRPC 性能。确实,在流上发送消息比新的一元 RPC 更快,但改进是固定的,并且具有更高的复杂性。相反,我们建议使用流式 RPC,因为它可以提供更高的应用程序(您的代码)性能或更低的应用程序复杂性。
Nis*_*ant 11
流确保消息按照发送的顺序传递,这意味着如果存在并发消息,就会出现某种瓶颈。
\nGoogle\xe2\x80\x99s gRPC 团队建议不要使用流而不是一元来提高性能,但尽管如此,仍然有人认为理论上流应该具有较低的开销。但事实似乎并非如此。
\n对于较少数量的并发请求,两者的延迟似乎相当。然而,对于更高的负载,一元调用的性能要高得多。
\n没有明显的理由我们应该更喜欢流而不是一元,因为使用流会带来其他问题,例如
\n这里的一些基准:https://nshnt.medium.com/using-grpc-streams-for-unary-calls-cd64a1638c8a
\n