多个请求进入 Java gRPC 服务器的同一个线程

Multiple requests go into same thread of Java gRPC Server

我有一些微服务是java写的,通过gRPC相互通信,放到AWS ECS中供运行ning使用。 当我 运行 服务并使用客户端程序调用这些服务时,我注意到一件很奇怪的事情。

通常,Tomcat 的线程池设置将确保多个请求将由相同数量的线程处理。但是当我 运行 我的程序有时会发生一个线程开始处理一个新请求时它已经在处理以前的请求。它使进程线程不安全,因此发生了错误。 它在普通服务上很少发生,并且当我同时向同一服务发送 10 个请求时一定会发生。

请问有没有我遗漏的设置?我在网上查到只能增加线程池大小。

---------2020/12/22 已编辑---------

通过进入调试模式,我看到一个RPC请求会被拆分成两个任务。一个用于消息本身,另一个用于从第一个任务返回的侦听器。我之前90%的错误都发生在这两个任务的时间间隔之间。 此外,当 运行ning 侦听器时,ServerImpl class 将使用上下文来处理每个 RPC 消息,以及方法单元中的每个步骤,覆盖覆盖侦听器中的所有书面代码。 因此它会在侦听器的 运行.

期间发生线程切换

StreamObserver's documentation中:

Implementations are not required to be thread-safe (but should be thread-compatible).

“线程兼容”是您问题的重要部分。这意味着您不能假设对实例的每次调用都将发生在同一个线程上。对于几乎所有非线程安全的 gRPC API 都是如此。这对大多数代码来说无关紧要,但会影响 ThreadLocals.

基本上,RPC 不“拥有”线程。相反,RPC 共享所有线程,当需要传递回调时,它只是找到 a 线程到 运行 回调。与用于 servlet 的大多数阻塞模型相比,这是一个允许更大扩展的异步模型,因为您可以用更少的线程为更多的 RPC 服务。但这意味着一旦您从回调中 return,同一个线程可能会用于其他 RPC 回调。