Netty中概念的理解
1)Channel:相当于一个Socket连接,类比java nio的SocketChannel;
2)EventLoop:反应堆线程,通过非阻塞方式执行I/O任务、定时任务等,类比java nio的Selector;I/O任务和定时任务都被抽象为事件,通过eventloop线程执行;
3)EventLoopGroup:反应堆线程组成的线程池,用于提升反应堆的处理能力及可用性;
4)ChannelFuture:采用Promise模式,异步通知I/O结果;
5)ChannelPipeline:一个channel中,用于处理事件的职责链,即一条完整的数据处理流程,包括输入、输出;
6)ChannelHandler:一条ChannelPipeline中的一个环节,可以只针对特定事件进行处理,或者仅对事件进行部分处理,如数据的编解码,以便于后续环节的处理;
7)ChannelInitializer:用于初始化一个Channel;
8)Bootstrap:用于引导和简化一个Channel的初始化过程;
9)ChannelGroup:用于对一组Channel进行分类和统一管理;
Netty中实体的关系
1)一个EventLoopGroup中包含一个或者多个EventLoop;
2)一个EventLoop在其生命周期内只和一个Thread绑定,且分配给该EventLoop的所有事件都在其绑定的Thread上处理;
3)一个Channel在其生命周期内只注册于一个EventLoop;
4)一个EventLoop可以用于处理一个或者多个Channel的事件;
5)一个EventLoopGroup可以被多个Channel所共享,通过Bootstrap单独为每一个Channel新建EventLoopGroup没有必要;
ChannelHandler的常用实现类
ByteBuf的实现方式
1)堆缓冲区:底层使用byte数组,数据直接缓冲在堆内存中;
优点:内存分配和释放效率高;
缺点:发送数据时,需要先从堆内存中拷贝数据到直接内存缓冲中;
2)直接缓冲区:使用直接内存块存放数据;
优点:发送数据时,零拷贝;
缺点:内存分配和释放比堆内存慢;
3)复合缓冲区:多个ByteBuf的组合,其中的ByteBuf即可以是堆缓冲区实现,又可以是直接缓冲区实现;
为什么服务端需要2个EventLoopGroup?
因为服务端需要启动本地端口,用于监听远程连接;同时,服务端还要和特定的远程连接进行通信。因而,第一个group用来监听本地端口的连接,仅包含一个ServerChannel。第二个group用来和已经建立连接的channel进行通信。
Channel和ChannelHandlerContext中write的区别:
Channel的write方法,会让时间从ChannelPipeline中的第一个ChannelHandler开始处理,使得数据完整的经过ChannelPipeline中的每一个环节;
ChannelHandlerContext的write方法:仅会从下一个ChannelHander开始处理,只会经过剩下的环节,并不会完整经过ChannelPipeline中的每一个环节;