前置条件
源码版本netty4.1
了解Java NIO、Reactor模型和Netty的基本使用。
解释一下:
- Java NIO:了解BIO和NIO的区别以及Java NIO基础API的使用
- Reactor模型:Netty是基于Netty模型对Java NIO封装的框架
- Netty的基本使用:先学会基本使用再看源码,这样可以带着看源码,事半功倍(这个api为啥这么样设计,这个对象又是在什么时候生成的巴拉巴拉)
Netty中的Reactor模型
Netty的线程模型参考了Reactor主从多线程模型,但又不完全一样。
图1,来源:Scalable IO in Java
此为Reactor主从多线程模型
- MainReactor负责监听客户端连接事件,创建连接后将连接交给SubReactor
- SubReactor负责监听读取事件,有事件发生时,交由Handler处理
-
Handler负责读写数据,实际的业务逻辑交由线程池处理(图中的Thread Pool)
读 → 线程池处理 → 异步等待线程池处理完成 → 写
图,2,来源于网络
此为Netty的线程模型
BossGroup和WorkerGroup可以简单理解为线程池(描述不准确,用来简单比喻),实际工作的是其内的NioEventLoop
- BossGroup负责监听客户端连接事件,创建连接后将连接交给WorkerGroup
- WorkerGrou负责监听读取事件,有事件发生时,读取数据并交由Handler处理
与Reactor主从多线程模型不同的是,Netty的Handler不负责读写数据,专注于数据的处理
Netty的组件
此部分来源于《Netty In Action》的摘抄
Channel接口
提供基本的 I/O 操作(bind()、connect()、read()和 write()),依赖于底层网络传输所提供的原语。类比就是Java网络编程中的Socket
EventLoop接口
定义了 Netty 的核心抽象,用于处理连接的生命周期中所发生的事件。
- 一个 EventLoopGroup 包含一个或者多个 EventLoop;
- 一个 EventLoop 在它的生命周期内只和一个 Thread 绑定;
- 所有由 EventLoop 处理的 I/O 事件都将在它专有的 Thread 上被处理;
- 一个 Channel 在它的生命周期内只注册于一个 EventLoop;
- 一个 EventLoop 可能会被分配给一个或多个 Channel。
注意,在这种设计中,一个给定 Channel 的 I/O 操作都是由相同的 Thread 执行的,实际
上消除了对于同步的需要。
EventLoopGroup接口
可以理解为EventLoop的池,用于创建和分配EventLoop
ChannelHandler接口
处理入站和出站数据的容器(简单理解就是处理业务逻辑的地方)
划分为入站处理(ChannelInboundHandler
)和出站处理(ChannelOutboundHandler
)
ChannelPipeline接口
提供了 ChannelHandler 链的容器,并定义了用于在该链上传播入站和出站事件流的 API。
责任链模式。
参考资料:
《Netty in Action》,Norman Maurer
《Scalable IO in Java》,Doug Lea