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

vqlkdk9b  于 2021-07-03  发布在  Java
关注(0)|答案(3)|浏览(431)

我有一些用java编写的微服务,通过grpc进行通信,并被放到aws服务器上运行。当我运行服务并使用客户端程序调用这些服务时,我注意到一件非常奇怪的事情。
通常,tomcat的线程池设置将确保相同数量的线程处理多个请求。但是当我运行我的程序时,有时会发生一个线程开始处理一个新的请求,而它已经在处理以前的请求了。它使进程线程不安全,因此发生了错误。这种情况在普通服务上非常罕见,而且必须在我同时向同一服务发送10个请求时发生。
请问有什么我错过的场景吗?我可以在互联网上搜索的是,我只能增加线程池的大小。

i7uaboj4

i7uaboj42#

通过进入调试模式,我看到一个rpc请求将被拆分为两个任务。一个用于消息本身,另一个用于从第一个任务返回的侦听器。我以前90%的错误都发生在这两个任务的时间间隔之间。此外,在运行listener时,serverimpl类将使用上下文来处理每个rpc消息,以及方法单元中的每个步骤,这些方法覆盖了过度ride侦听器中的所有编写的代码。因此,在侦听器运行期间会发生线程切换。

xoefb8l8

xoefb8l83#

StreamObserver 的文档:
实现不需要是线程安全的(但应该是线程兼容的)。
“线程兼容”是你提问的重要部分。这意味着您不能假设对示例的每个调用都发生在同一个线程上。这对于几乎所有非线程安全的grpcapi都是如此。这对大多数代码来说并不重要,但会影响 ThreadLocal s。
基本上,线程不是由rpc“拥有”的。相反,rpc共享所有线程,当需要传递回调时,它只会找到一个线程来运行回调。这是一个异步模型,与servlet使用的主要阻塞模型相比,它允许更大的伸缩性,因为您可以用更少的线程服务更多的rpc。但这意味着一旦从回调返回,同一个线程就可以用于其他rpc回调。

相关问题