是增加工作线程的数量还是在 Netty 中创建自己的线程池更好?

Oli*_*ler 2 java multithreading netty

假设我们的 Netty 服务器 (4.1.32) 响应 HTTP 调用。我们进一步假设它必须在回答传入请求之前执行某些阻塞操作,例如,它必须执行传出调用(此处使用不同的库)来加载外部数据。

具有持久连接的NioEventLoopGroup的线程数讨论

如果我的 messageReceived 方法阻塞或需要很长时间才能完成,会发生什么情况?

@Maksym 回应

您应该避免在处理程序中使用线程阻塞操作。

很明显,工作线程的数量是有限的。因此,有效地阻塞所有可用的工作线程意味着 Netty 将对任何进一步的请求进行排队,直到工作线程变得可用。

另一方面,按照建议将阻塞操作移至我自己的线程上,将对线程切换产生性能影响,而反过来,可用硬件将阻塞的是我自己的线程池。恕我直言,使用我自己的线程池只会增加另一层复杂性,但不会提高性能。相反,我宁愿增加工作线程的最大数量,并让 Netty 完成对请求进行排队的工作。

这里建议的做法是什么?

ewr*_*ner 5

您应该使用自己的线程池。Netty 工作线程在许多连接之间共享,如果您阻止处理一个请求,则会损害其他请求。该设计假设您的代码快速返回,如果您需要阻塞,则必须为此使用单独的线程。如果您需要执行非常昂贵的计算,则同样适用,在另一个线程中执行并返回。

如果您做过任何 Swing 编程,您可以将其与 GUI 线程进行比较。如果您阻止 GUI 线程,用户界面将挂起并变得无响应。不适合用户界面,也不适合高性能网络应用程序!

编辑:非常清楚,对于经典 IO,一个线程通常被分配给一个请求,如果请求阻塞,那不是世界末日,如果线程池足够大,其他线程可以处理其他请求。使用 NIO,你不会得到一个线程来处理你的请求,你会被一个处理 IO 的线程调用来处理许多请求来处理一个事件,并且你应该尽快执行此操作,以便该线程可以转移到另一个线程要求。阻塞对于服务器来说确实很糟糕。