用于长寿命流的Java gRPC服务器有效实现
我想了解gRPC框架的一部分,用于长期流的资源管理。 假设我们有无限的稀有事件源(每秒一次左右),我们希望通过grpc流将这些事件流到客户端。 事件由服务器上的单个应用程序线程生成 我看到两种可能的流式事件实现:用于长寿命流的Java gRPC服务器有效实现,java,grpc,grpc-java,Java,Grpc,Grpc Java,我想了解gRPC框架的一部分,用于长期流的资源管理。 假设我们有无限的稀有事件源(每秒一次左右),我们希望通过grpc流将这些事件流到客户端。 事件由服务器上的单个应用程序线程生成 我看到两种可能的流式事件实现: 在rpc调用中旋转调用方线程,并通过(阻塞)队列与源进行通信 向事件生成线程公开StreamObserver,并从中填充所有客户端流 选项一看起来很简单,但线程数量有点过多——对于稀疏流,每个客户机一个线程似乎有点过分了。每个线程占用一些堆调度程序,以此类推 选项二看起来对资源更为友好
但我仍然想得到答案。从gRPC的角度来看,这两种方法都很好。在方便的时候,您可以自由地使用1个客户端、1个线程的方法。对于流式传输的情况,通常最好避免在调用线程中旋转,但您可以使用第二个线程来发送;这很正常。另一方面,将
StreamObserver
s传递给单个线程进行管理具有资源优势,也是一种很好的方法
您应该考虑如何响应慢客户机,当事件生成的速度比它们发送的速度快(即流量控制)时,
您需要将提供的StreamObserver
转换为ServerCallStreamObserver
,以访问其他API。它提供和用于检测慢速客户端。GRPCJava允许您调用onNext(…)
,即使在未准备就绪的情况下,但这样做会导致缓冲区失效
on ready处理程序是一个回调,它使用与调用线程相同的线程,因此如果在调用线程中旋转,您将无法接收该回调。这就是为什么对于流式处理,通常最好避免在调用线程中旋转
使用专用的发送线程具有以下优点:队列清晰,生产者和消费者分离。您可以选择队列大小,并决定当该队列已满时要执行的操作。在一个线程中直接与
StreamObserver
s交互可以减少资源使用。两种选择的复杂性各不相同。“正确”的方法选择是基于规模、资源考虑、服务细节和您的偏好。谢谢您,Eric,快速详细的回复!事实上,单响应线程看起来更加资源友好。我将研究有关流控制的ServerCallStreamObserver API。虽然对我来说,更新所有客户端而不删除任何消息是非常重要的。也许我应该调查一下比迪的沟通。关于缓冲的问题-有没有控制缓冲区大小的方法?缓冲区将不受限制地增长,只有isReady()提示告诉您它的大小正在增长。是允许配置isReady()阈值的功能请求。