下面我们对Netty服务端创建的关键步骤进行讲解。
步骤1:创建ServerBootstrap实例
代码 ServerBootstrap b = new ServerBootstrap();
ServerBootstrap是Netty服务端的启动辅助类,它提供了一系列的方法用于设置服务端启动相关的参数。ServerBootstrap只有一个无参的构造函数,因为它的参数太多了AND变化太多,采用Builder设计模式解决。
步骤2:设置并绑定Reactor线程池
代码 :
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
b.group(bossGroup, workerGroup)
Netty的Reactor线程池是EventLoopGroup,它实际就是EventLoop的数组。EventLoop的职责是处理所有注册到本线程多路复用器Selector上的Channel,Selector的轮询操作由绑定的EventLoop线程run方法驱动,在一个循环体内循环执行。值得说明的是,EventLoop的职责不仅仅是处理网络I/O事件,用户自定义的Task和定时任务Task也统一由EventLoop负责处理,这样线程模型就实现了统一。从调度层面看,也不存在在EventLoop线程中再启动其它类型的线程用于异步执行其它的任务,这样就避免了多线程并发操作和锁竞争,提升了I/O线程的处理和调度性能。
步骤3:设置并绑定服务端Channel
代码:b.channel(NioServerSocketChannel.class)
作为NIO服务端,需要创建ServerSocketChannel,Netty对原生的NIO类库进行了封装,对应实现是NioServerSocketChannel。对于用户而言,不需要关心服务端Channel的底层实现细节和工作原理,只需要指定具体使用哪种服务端Channel即可。因此,Netty的ServerBootstrap方法提供了channel方法用于指定服务端Channel的类型。Netty通过工厂类,利用反射创建NioServerSocketChannel对象。由于服务端监听端口往往只需要在系统启动时才会调用,因此反射对性能的影响并不大。
步骤4:链路建立的时候创建并初始
化ChannelPipeline cv
代码
b.childHandler(newChannelInitializer<SocketChannel>(){}
ChannelPipeline并不是NIO服务端必需的它本质就是一个负责处理网络事件的职责链,负责管理和执行ChannelHandler。网络事件以事件流的形式在ChannelPipeline中流转,由ChannelPipeline根据ChannelHandler的执行策略调度ChannelHandler的执行典型的网络事件如下:
整个服务端的代码,我会在讲完步骤后贴出。