0x01 Netty 核心组件
- Bootstrap & ServerBootstrap
- Channel
- ChannelFuture
- EventLoop & EventLoopGroup
- ChannelHandler
- ChannelPipeline
0x02 Bootstrap & ServerBootstrap
2个类均继承AbstractBootstrap。
Bootstrap 用于启动一个 Netty TCP 客户端,或者 UDP 的一端。
- 通常使用
#connet(...)
方法连接到远程的主机和端口,作为一个 Netty TCP 客户端。- 也可以通过
#bind(...)
方法绑定本地的一个端口,作为 UDP 的一端。- 仅仅需要使用一个 EventLoopGroup
ServerBootstrap 往往是用于启动一个 Netty 服务端。
- 通常使用
#bind(...)
方法绑定本地的端口上,然后等待客户端的连接。- 使用两个 EventLoopGroup 对象( 当然这个对象可以引用同一个对象 ):第一个用于处理它本地 Socket 连接的 IO 事件处理,而第二个责负责处理远程客户端的 IO 事件处理。
- TODO 1 添加源码分析
- TODO 2 添加常见面试问题
0x03 Channel
Channel 是 Netty 网络操作抽象类,它除了包括基本的 I/O 操作,如 bind、connect、read、write 之外,还包括了 Netty 框架相关的一些功能,如获取该 Channel 的 EventLoop 。
0x04 EventLoop && EventLoopGroup
Netty 基于事件驱动模型,使用不同的事件来通知我们状态的改变或者操作状态的改变。它定义了在整个连接的生命周期里当有事件发生的时候处理的核心抽象。
Channel 为Netty 网络操作抽象类,EventLoop 负责处理注册到其上的 Channel 处理 I/O 操作,两者配合参与 I/O 操作。
EventLoopGroup 是一个 EventLoop 的分组,它可以获取到一个或者多个 EventLoop 对象,因此它提供了迭代出 EventLoop 对象的方法。
注意点⚠️
- 一个 EventLoopGroup 包含一个或多个 EventLoop ,即 EventLoopGroup : EventLoop =
1 : n
。- 一个 EventLoop 在它的生命周期内,只能与一个 Thread 绑定,即 EventLoop : Thread =
1 : 1
。- 所有有 EventLoop 处理的 I/O 事件都将在它专有的 Thread 上被处理,从而保证线程安全,即 Thread : EventLoop =
1 : 1
。- 一个 Channel 在它的生命周期内只能注册到一个 EventLoop 上,即 Channel : EventLoop =
n : 1
。- 一个 EventLoop 可被分配至一个或多个 Channel ,即 EventLoop : Channel =
1 : n
。当一个连接到达时,Netty 就会创建一个 Channel,然后从 EventLoopGroup 中分配一个 EventLoop 来给这个 Channel 绑定上,在该 Channel 的整个生命周期中都是有这个绑定的 EventLoop 来服务的。
0x05 ChannelFuture
Netty 为异步非阻塞,即所有的 I/O 操作都为异步的,因此,我们不能立刻得知消息是否已经被处理了。Netty 提供了 ChannelFuture 接口,通过该接口的 #addListener(...)
方法,注册一个 ChannelFutureListener,当操作执行成功或者失败时,监听就会自动触发返回结果。
0x06 ChannelHandler
ChannelHandler 有两个核心子类 ChannelInboundHandler 和 ChannelOutboundHandler,其中 ChannelInboundHandler 用于接收、处理入站( Inbound )的数据和事件,而 ChannelOutboundHandler 则相反,用于接收、处理出站( Outbound )的数据和事件。
0x07 ChannelPipeline
ChannelPipeline 为 ChannelHandler 的链,提供了一个容器并定义了用于沿着链传播入站和出站事件流的 API 。一个数据或者事件可能会被多个 Handler 处理,在这个过程中,数据或者事件经流 ChannelPipeline ,由 ChannelHandler 处理。在这个处理过程中,一个 ChannelHandler 接收数据后处理完成后交给下一个 ChannelHandler,或者什么都不做直接交给下一个 ChannelHandler。
当数据流进入ChannelPipeline时是从头部开始依次传递到每一个handler,直到尾部。相对的,如果数据是被写出,则从尾部开始传递到头部。
- ctx.writeAndFlush与ctx.channel().writeAndFlush的区别
ctx.writeAndFlush()是将数据从当前节点开始向前传递,ctx.channel().writeAndFlush是强制从channel的尾部开始将数据向前传递
类似的还有ctx.fireChannelRead() 和ctx.channel().fireChannelRead()
- 本文作者: Noisy
- 本文链接: http://Metatronxl.github.io/2019/10/22/Netty-面试题整理-二/
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!