Netty 服务器老板和工作线程池大小

Netty server boss and worker thread pool sizes

如果我对 Netty 服务器的理解是正确的,主 boss 事件循环线程池(默认大小为 2*availableProcessors)接受客户端连接,然后将请求处理工作卸载到工作线程。

现在,我的问题是,工作线程的线程池大小应该是多少?如果 worker 正在执行一些阻塞操作,比如等待网络调用响应,那么 worker 线程池是否应该足够大(比如 200 个线程)来处理并发客户端请求,因为每个 worker 线程都被阻塞以服务于客户端请求?我看到大多数 ServerBootstrap 示例显示工作线程池大小为 2xAvailableProcessors,这与主线程池大小相同。这不会将并发客户端请求处理的数量限制为 2xAvailableProcessors 吗?

更让我感到困惑的是,我看到另一个正在使用的线程池称为处理程序线程池 (EventExecutorGroup),并表示此线程池处理请求处理。那worker线程池有什么用呢?

三种类型的线程池在我遇到的例子中创建如下。

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(10);
EventExecutorGroup handlerThread = new DefaultEventExecutorGroup(20);

并且如果工作线程正在执行一些 CPU 密集型进程(而不是在上面的示例中等待网络调用响应),工作线程将与主 boss 线程竞争。这种情况不会使老板线程变慢,从而使客户端连接在队列中等待被接受或拒绝吗?在这种情况下,我相信服务器的性能将与传统的阻塞服务器相同。您能分享一下您对此的看法吗?

Now, the question I have is, what should be the thread pool size for worker threads? If worker is doing some blocking operating say waiting for a network call response

您永远不应该阻塞 netty 工作线程,尤其是对于网络 I/O —— 这就是使用像 netty 这样的 non-blocking 异步框架的全部意义所在。也就是说,为了与 synchronous/blocking 代码如 JDBC 互操作,netty 提供了一种使用 EventExecutorGroup 将此类执行卸载到单独的线程池中的方法。看看 Netty docs 中的这个片段:

 // Tell the pipeline to run MyBusinessLogicHandler's event handler methods
 // in a different thread than an I/O thread so that the I/O thread is not blocked by
 // a time-consuming task.
 // If your business logic is fully asynchronous or finished very quickly, you don't
 // need to specify a group.
 pipeline.addLast(group, "handler", new MyBusinessLogicHandler());

And if worker threads are doing some CPU intensive process

这是一个更笼统的问题,与 netty 并不完全相关,但是如果您的工作负载非常 CPU 密集,那么使用异步网络 I/O 框架可能不适合您。