Netty 4-EventLoopGroup-EventLoop-EventExecutor-Thread affinity

Netty 4-EventLoopGroup-EventLoop-EventExecutor-Thread affinity,netty,Netty,我正在研究Netty 4.0.0.Alpha5代码,以了解线程是如何处理的。我还阅读了关于Netty 4新线程模型的介绍 据我所知,目标是: 线程关联,将通道粘贴到单个线程(EventLoop)。我猜这种方法是为了减少缓存未命中,并改善NUMA硬件上的情况 所以,我想知道我的解释是否正确。如果我是对的,那么就会出现以下问题: 在ChannelPipeline中使用可能长时间运行的ChannelHandler(例如数据库操作)可能会阻止EventLoop(线程),因此会阻止分配给同一Even

我正在研究Netty 4.0.0.Alpha5代码,以了解线程是如何处理的。我还阅读了关于Netty 4新线程模型的介绍

据我所知,目标是:

  • 线程关联,将通道粘贴到单个线程(EventLoop)。我猜这种方法是为了减少缓存未命中,并改善NUMA硬件上的情况
所以,我想知道我的解释是否正确。如果我是对的,那么就会出现以下问题:

  • 在ChannelPipeline中使用可能长时间运行的ChannelHandler(例如数据库操作)可能会阻止EventLoop(线程),因此会阻止分配给同一EventLoop(线程)的所有其他通道。这种解释正确吗
  • 为了避免这个问题,我可以为长时间运行的ChannelHandler使用EventExecutor,但根据文档(请参阅上面的链接),通道再次被卡在其EventExecutor内的单个线程上,因此可能会再次阻塞分配给同一线程的其他通道(在EventExecutor内)。我错过了什么还是真的

我只是想了解为什么事情是这样的,并获得一些关于Netty 4的设计意图的信息。

这两个问题都是正确的。通过将处理程序分配给非I/O事件组,可以防止I/O线程被长时间运行的操作(如数据库访问)阻塞。根据处理程序的操作,您可以指定一个较大的
EventExecutorGroup
。它与通常的线程池没有太大区别。如果线程池忙,任何执行长时间运行任务的尝试都将排队。

对于Netty 3,您的两点也是正确的

Netty 3有一个boss和worker线程的概念。boss线程负责接受新的连接,然后将其卸载到工作线程。 创建
NioServerSocketChannelFactory
时,工作线程的数量是可配置的

现在Netty4已经分别用父事件循环和子事件循环替换了这些boss线程和工作线程。 但核心思想仍然是一样的:为了摆脱“每个连接一个线程”模式,您必须为一个线程分配多个连接。

因此,当您创建一个服务器时,将有一个由N个线程组成的固定池,专门用于处理连接。如果连接数低于N,则每个线程不会有多个连接。另一方面,如果有N个以上的连接,某些线程将管理多个连接。这是以循环方式完成的,请查看

我关心的主要是坚持单线程模式。在传统的线程池中,只要不是所有线程都被阻塞,进程就会发生。但是,如果多个任务(事件)绑定到同一特定线程,则它们可能会相互阻塞(排队),即使该池中仍有空闲线程。例如,Doug Lea的ForkJoinPool通过利用工作窃取来避免这种情况。