Netty的EventLoopGroup线程池是如何进行初始化的?

面试官:能请你解释一下Netty中的EventLoopGroup线程池是如何进行初始化的吗?

候选人:Netty中的EventLoopGroup在初始化时会根据CPU核心数创建NioEventLoop线程,默认是核心数*2。

每个NioEventLoop负责管理部分SocketChannel客户端连接,并使用自己的Selector来轮询这些连接上的网络事件。

也就是说,会初始化一个由NioEventLoop组成的线程池,每个线程BIND一个Selector,负责轮询一组客户端连接的网络事件。

面试官:说的很好,可否扩展一下每个NioEventLoop线程具体是如何使用Selector的?

候选人:好的。在Netty服务器端,会有一个Acceptor线程,使用ServerSocketChannel 和 Selector 监听客户端连接。

当有新连接时,Acceptor会将SocketChannel分配给一个NioEventLoop线程

每个NioEventLoop线程会通过自己的Selector轮询已经分配给它的那部分SocketChannel。当Selector检测到可读写事件时,就会触发后续的Handler处理。

所以每个NioEventLoop负责独立地、高效地使用Selector轮询绑定的一组客户端连接,实现并发处理。

面试官: 能更详细地描述一下NioEventLoop线程是如何使用Selector和触发Handler吗?

候选人:好的。在Netty中,每个NioEventLoop线程在初始化时会创建一个Selector,然后在一个while(true)的循环中反复调用selector.select()方法监听 Channel 上的事件。

当有事件发生时,select()方法会立即返回。NioEventLoop会从返回的selectionKey集合中遍历获取所有的已就绪的 Channel。

对于每个就绪的 Channel,NioEventLoop会调用 unsafe.read() 方法从 Channel 中读取数据,读取完成后会通过 Pipeline 触发关联的 ChannelHandler 的 channelRead() 方法进行处理。

如果读取的数据是一个请求消息,会经过一系列关联的 Decoder、Handler 处理,最后编码一个响应写回 Channel。

在整个过程中,NioEventLoop 充当 Reactor 角色,通过 Selector 监听 IO 事件,然后触发 Pipeline 中关联的 Handler 进行业务处理,实现了RequestHandler 和处理代码的解耦

所以每个 NioEventLoop 独立地利用 Selector 和 Pipeline 机制对绑定的 Channel 进行高效的 IO 事件处理和业务处理。不同的 NioEventLoop之间通过多线程实现并发。

更多精彩内容请查看我的个人介绍。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容