Netty-线程模型
前言
想要了解Netty之前,我们需要先去了解一下Nio的运行机制。在使用Netty进行服务端开发的时候,我们通常会设置下面的代码:
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(2);
下面就从线程模型方面去解释上面代码设置的的原因。
Reactor线程模型(Nio的多路复用+线程池)
-
Reactor模式是基于事件驱动开发的,核心组成部分包括Reactor和线程池,其中Reactor负责监听和分配事件,线程池负责处理事件,而根据Reactor的数量和线程池的数量,又将Reactor分为三种模型:
- 单线程模型 (单Reactor单线程)
- 多线程模型 (单Reactor多线程)
- 主从多线程模型 (多Reactor多线程)
单线程模型
* Reactor内部通过selector 监控连接事件,收到事件后通过dispatch进行分发。
- 如果是建立连接事件:那么一定是被包含acceptor的selectedKey接收。这时候就会调用 new一个Handler 并且SocketChannel 注册为Read事件,并将这个handler 与这个selectedKey 相联系
- 如果是读写事件:直接利用k.attachment()调出对应Handler来处理读业务 和写业务。
- Handler完成read->(decode->compute->encode)->send的业务流程
- 这种模型好处是简单,坏处却很明显,当某个Handler阻塞时,会导致其他客户端的handler和accpetor都得不到执行,无法做到高性能,只适用于业务处理非常快速的场景。
多线程模型
- 和单线程模型差不多,差别在于在读和写的时候,将任务放在线程池里面去,并行处理。
主从多线程模型
- 多设置几个selector 去接收事件!每一次接收到就注册到不同的selector去,让其分流处理事件
Netty 的主从多线程模型
- 主从多线程模型是有多个Reactor,也就是存在多个selector,所以我们定义一个bossGroup和一个workGroup,核心代码如下:
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new ServerHandlerInitializer());
注意:其实在Netty中,bossGroup线程池最终还是只会随机选择一个线程用于处理客户端连接,与此同时,NioServerSocetChannel绑定到bossGroup的线程中,NioSocketChannel绑定到workGroup的线程中