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

Is it better to increase the number of worker threads or create my own thread pool in Netty?

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

Number of threads for NioEventLoopGroup with persistent connections讨论

What happens if my messageReceived method blocks on something or takes a long time to complete?

@Maksym 回复

You should avoid using thread blocking actions in your handlers.

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

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

此处建议的做法是什么?

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

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

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