Netty的核心组件
Netty是什么?
Netty的核心组件
- ByteBuf
- Channel
- ChannelPipeline
- ChannelHandler
- EventLoop
- EventLoopGroup
- Bootstrap和ServerBootstrap
ByteBuf
网络数据的载体,数据全都包装在ByteBuf中进行传输。网络数据的基本单位是字节。
Channel
Java Nio中Channel的作用相当于Java IO中的Stream,网络IO操作是在Channel上进行的。Netty中的Channel是对Java Nio中Channel的进一步包装,不仅仅提供了基本的IO操作,如bind,connect,read,write之外,还提供了Netty框架的一些功能,如获取channel的pipeline,eventloop等。
Java Nio中的SocketChannel和ServerSocketChannel没有统一的视图,使用不方便,而Netty通过包装Java Nio中的Channel提供了统一的视图,并且在不同的子类中实现不同的功能,公共功能在父类中进行实现,最大程度实现了接口的重用。并且将Netty相关的功能类聚合在channel中,由channel进行统一调度和分配,功能实现更加灵活。
ChannelHandler
ChannelHandler 为 Netty 中最核心的组件,它充当了所有处理入站和出站数据的应用程序逻辑的容器。ChannelHandler 主要用来处理各种事件,这里的事件很广泛,比如可以是连接、数据接收、异常、数据转换等。
ChannelHandler 有两个核心子类 ChannelInboundHandler 和 ChannelOutboundHandler,其中 ChannelInboundHandler 用于接收、处理入站数据和事件,而 ChannelOutboundHandler 则相反。
ChannelInitializer也是一个ChannelHandler,当ChannelInitializer被注册到ServerBootstrap后,当 ChannelInitializer.initChannel() 方法被调用时,ChannelInitializer 将在 ChannelPipeline 中安装一组自定义的 ChannelHandler,当安装完成之后,最后ChannelInitializer会从ChannelPipeline中移除。
ChannelPipeline
ChannelPipeline其实就是对Channel进行处理的流水线,是ChannelHandler的容器,承载了很多ChannelHandler。从入站到出站,数据流经ChannelPipe,依次由ChannelHandler进行处理。
EventLoop
Netty是事件驱动模型,使用不同的时间来通知我们状态的改变或者是操作状态的改变,EventLoop定义了在生命周期中有事件发生,用来处理连接的一个核心抽象。在内部,会为每一个channel分配一个EventLoop。
EventLoop本身只由一个线程驱动,其处理了一个Channel的所有I/O事件,并且在该EventLoop的整个生命周期内都不会改变。这个简单而强大的设计消除了你可能有的在ChannelHandler实现中需要进行同步的任何顾虑。
Netty应用程序尽可能的重用EventLoop,以减少创建线程带来的开销。
EventLoopGroup
EventLoop是通过EventLoopGroup来进行管理的,客户端一般只需要一个EventLoopGroup,而服务器端需要两个EventLoopGroup,一个负责监听客户端的连接,另外一个则是负责每一个连接中网络IO事件的读写(也可以只使用一个EventLoopGroup,此时将在两个场景下调用同一个EventLoopGroup)。(本质上其实相当于是线程池)
EventLoop和EventLoopGroup的特性:
1、一个 EventLoopGroup 包含一个或者多个 EventLoop;
2、一个 EventLoop 在它的生命周期内只和一个 Thread 绑定;
3、所有由 EventLoop 处理的 I/O 事件都将在它专有的Thread 上被处理;
4、一个 Channel 在它的生命周期内只注册于一个EventLoop;
5、NIO中,一个 EventLoop 分配给多个 Channel(面对多个Channel,一个 EventLoop 按照事件触发,顺序执行); OIO中,一个 EventLoop 分配给一个 Channel。
Bootstrap和ServerBootstrap
Bootstrap和ServerBootstrap是引导类,一个用于客户端,一个用于服务端,它主要对应用程序进行配置,并使其运行起来的过程。Netty处理引导的方式是使你的应用程序和网络层相隔离。
BootStrap 是客户端的引导类,Bootstrap 在调用 bind()(连接UDP)和 connect()(连接TCP)方法时,会新创建一个 Channel,仅创建一个单独的、没有父 Channel 的 Channel 来实现所有的网络交换。(为啥要创建两个channel,这里不是很懂)
ServerBootstrap 是服务端的引导类,ServerBootstarp 在调用 bind() 方法时会创建一个 ServerChannel 来接受来自客户端的连接,并且该 ServerChannel 管理了多个子 Channel 用于同客户端之间的通信。