学一学Netty中的NioEventLoopGroup
一个Netty程序启动时,至少要指定一个EventLoopGroup 假如我们使用NIO,那我们通常使用NioEventLoopGroup 使用BIO,那我们可以初始化OioEventLoopGroup
官方DOC
上图时Netty(4.1.6)中EventLoopGroup的解释 在事件循环期间可对EventExecutorGroup进行Channel的注册,然后供后续使用 到这里有一个模糊的概念,EventLoopGroup可以对Channel进行注册
方法实现
通过其提供的接口方法可以发现EventLoopGroup定义了Channel的注册规范
EventLoopGroup结构图
父结构
这里发现它的顶层父类是Executor对象。我们知道Netty是基于Java实现的RPC框架 那么看到这里不难理解,EventLoopGroup其实是和线程相关的 Netty本质又是Reactor模型的实现,那么EventLoopGroup和Reactor肯定是有关系的
EventLoopGroup与Reactor
EventLoopGroup workerGroup = new NioEventLookGroup();
Bootstrap boot = new Bootstrap();
boot.group(workerGroup);
这里初始化了一个NioEventLookGroup对象,那么先来看一下EventLoopGroup的子结构 通过其子结构类图可以发现一些端倪
SingleThreadEventLoop : 在一个线程中执行所有提交的任务
MultithreadEventLoopGroup : 多线程并发处理提交的任务
EmbeddedEventLoop : 用来测试
ThreadPerChannelEventLoop : 提供OIO的处理模式,每一个EventLoop对应一个线程对应一个Channel
通过NioEventLoopGroup窥视其冰山一角
NioEventLoopGroup官方DOC 使用NIO模型,基于Channel选择了Selector选择器
初始化 未传入参数的话,使用默认线程数。并且在初始化过程中创建一个SelectorProvider对象,后续用来提供Selector 默认线程数:处理器数 * 2
Bootstrap—group方法
EventLoopGroup workerGroup = new NioEventLookGroup();
Bootstrap boot = new Bootstrap();
boot.group(workerGroup);
EventLoopGroup group = new NioEventLookGroup();
// 与客户端不同,服务端使用 ServerBootstrap
ServerBootstrap boot = new ServerBootstrap();
boot.group(group);
服务端group方法实现 这里我们可以发现,服务端的boss线程和worker线程实际上是同一个线程
到这里我们可以发现,当我们设置单线程的时候。 NioEventLoopGroup线程池的数量只设置为1 Netty中的Acceptor和后续所有的接收到的请求都是在一个线程中处理的 对应Reactor线程模型,就相当于Reactor的单线程模型
单线程模型
EventLoopGroup group = new NioEventLookGroup();
// 与客户端不同,服务端使用 ServerBootstrap
ServerBootstrap boot = new ServerBootstrap();
boot.group(group);
多线程模型
// 设置 n > 1的线程数,当然要合理,不能无限大
EventLoopGroup group = new NioEventLookGroup(n);
// 与客户端不同,服务端使用 ServerBootstrap
ServerBootstrap boot = new ServerBootstrap();
boot.group(group);
主从线程模型
EventLoopGroup boos = new NioEventLookGroup();
EventLoopGroup work = new NioEventLookGroup();
// 与客户端不同,服务端使用 ServerBootstrap
ServerBootstrap boot = new ServerBootstrap();
boot.group(boos, worker);
看代码,通过对parentGroup和childGroup进行不同的处理,确定其不同的工作职责
NioEventLoopGroup如何工作的
现在,对NioEventLoopGroup的作用以及原理有了一个基本的认识 那么当任务过来的时候是如何被执行的呢
NioEventLoopGroup的实例化
通过其实例化过程入手 调用到 其父类 MultithreadEventLoopGroup 的构造方法,进行线程相关参数的设置
调用到 MultithreadEventExecutorGroup 的 构造方法,重点看其中的 newChild 方法 根据线程数量做循环 又回调到 NioEventLoopGroup 的 newChild 方法
走到 NioEventLoop 的构造方法 走到这里看到了熟悉的方法openSelector()选择器出现了
NioEventLoopGroup工作模型