Netty逻辑架构
Netty 的逻辑处理架构为典型网络分层架构设计,网络通信层、事件调度层、服务编排层
。
一、 网络通信层
网络通信层的职责是执行网络 I/O 的操作。它支持多种网络协议和 I/O 模型的连接操作。当网络数据读取到内核缓冲区后,会触发网络事件,这些网络事件会分发给事件调度层进行处理。
1.1 BootStrap&ServerBootStrap
网络通信层的核心组件 包含 BootStrap、ServerBootStrap、Channel 三个组件。一个为用于客户端引导的 Bootstrap ,另一个为用于服务端引导的 ServerBootStrap ,它们都继承自抽象类 AbstractBootstrap。
Boss
对应 Reactor
模型中的 MainReactor
,Worker
对应 Reactor
模型的 SubReactor
。
1.2 channel
网络通信的载体, 提供基本的API 用于网络 I/O 操作,如 register、bind、connect、read、write、flush
等。有多种状态,如连接建立、连接注册、数据读写、连接销毁等。
1.3 总结
- BootStrap 和 ServerBootStrap 分别负责客户端和服务端的启动,它们是非常强大的辅助工具类,串联了 Netty 的系列核心组件;
- Channel 是网络通信的载体,提供了与底层 Socket 交互的能力。
二、事件调度层
事件调度层的职责是通过 Reactor 线程模型对各类事件进行聚合处理,通过 Selector 主循环线程集成多种事件( I/O 事件、信号事件、定时事件等),实际的业务处理逻辑是交由服务编排层中相关的 Handler 完成。
事件调度层的核心组件 包括 EventLoopGroup、EventLoop。
2.1 EventLoopGroup & EventLoop
EventLoopGroup 本质是一个线程池,主要负责接收 I/O 请求,并分配线程执行处理请求。
EventLoopGroup 是一个线程池,我们发现它继承了 Executor 类,可以证明它是一个线程池。
EventLoop 是一个个线程,由 EventLoopGroup 负责分配 EventLoop 进行处理事件。
从上图中,我们可以总结出 EventLoopGroup、EventLoop、Channel 的几点关系。
- 一个 EventLoopGroup 往往包含一个或者多个 EventLoop。EventLoop 用于处理 Channel 生命周期内的所有 I/O 事件,如 accept、connect、read、write 等 I/O 事件。
- EventLoop 同一时间会与一个线程绑定,每个 EventLoop 负责处理多个 Channel。
- 每新建一个 Channel,EventLoopGroup 会选择一个 EventLoop 与其绑定。该 Channel 在生命周期内都可以对 EventLoop 进行多次绑定和解绑。
NioEventLoopGroup 继承于 MultithreadEventLoopGroup,是基于 NIO 模型开发的,可以把 NioEventLoopGroup 理解为一个线程池,每个线程负责处理多个 Channel,而同一个 Channel 只会对应一个线程。EventLoopGroup 是 Netty 的核心处理引擎。
EventLoopGroup 和 Reactor 线程模型到底是什么关系呢?其实 EventLoopGroup 是 Netty Reactor 线程模型的具体实现方式,Netty 通过创建不同的 EventLoopGroup 参数配置,就可以支持 Reactor 的三种线程模型:
- 单线程模型 :EventLoopGroup 只包含
一个 EventLoop
,Boss 和 Worker 使用同一个EventLoopGroup; - 多线程模型 :EventLoopGroup 包含
多个 EventLoop
,Boss 和 Worker 使用同一个EventLoopGroup; - 主从多线程模型:EventLoopGroup 包含多个 EventLoop,Boss 是主 Reactor,Worker 是从 Reactor,它们分别使用不同的 EventLoopGroup,主 Reactor 负责新的网络连接 Channel 创建,然后把 Channel 注册到从 Reactor。
三、服务编排层
服务编排层的职责是负责组装各类服务,它是 Netty 的核心处理链,用以实现网络事件的动态编排和有序传播 。 核心组件 : ChannelPipeline 、ChannelHandler、ChannelHandlerContext。
3.1 ChannelPipeline
**负责组装各种 ChannelHandler,**数据的编解码以及加工处理操作都是由 ChannelHandler 完成的。ChannelPipeline是ChannelHandler的实例列表,内部形成双向链表将ChannelHandler链接在一起。当I/O事件触发时,Pipeline会依次调用Handler对channel数据进行处理。
ChannelPipeline 是线程安全的
,因为每一个新的 Channel 都会对应绑定一个新的 ChannelPipeline。一个 ChannelPipeline 关联一个 EventLoop,一个 EventLoop 仅绑定一个线程
ChannelPipeline 有入站 ChannelInboundHandler 和出站 ChannelOutboundHandler 两种处理器
客户端和服务端都有各自的 ChannelPipeline。以客户端为例,数据从客户端发向服务端,该过程称为出站 ,反之则称为入站。数据入站会由一系列 InBoundHandler 处理,然后再以相反方向的 OutBoundHandler 处理后完成出站。 编码 Encoder 是出站操作,解码 Decoder 是入站操作
3.2 ChannelHandler & ChannelHandlerContext
每创建一个 Channel 都会绑定一个新的 ChannelPipeline,ChannelPipeline 中每加入一个 ChannelHandler 都会绑定一个 ChannelHandlerContext。
ChannelHandlerContext是对ChannelHandler的一种封装,可以知道 ChannelPipeline 和 ChannelHandler 的关联关系。可以实现 ChannelHandler 之间的交互 ,ChannelHandlerContext 包含了ChannelHandler 生命周期所有事件,如 connect、bind、read、flush、write、close 等。
四、组件关系梳理
- 服务端启动初始化时有
Boss EventLoopGroup
和Worker EventLoopGroup
两个组件,其中 Boss 负责监听网络连接事件。当有新的网络连接事件到达时,则将 Channel 注册到 Worker EventLoopGroup。 - Worker EventLoopGroup 会被分配一个 EventLoop 负责处理该 Channel 的读写事件。每个 EventLoop 都是单线程的,通过 Selector 进行事件循环。
- 当客户端发起 I/O 读写事件时,服务端 EventLoop 会进行数据的读取,然后通过 Pipeline 触发各种监听器进行数据的加工处理。
- 客户端数据会被传递到 ChannelPipeline 的第一个 ChannelInboundHandler 中,数据处理完成后,将加工完成的数据传递给下一个 ChannelInboundHandler。
- 当数据写回客户端时,会将处理结果在 ChannelPipeline 的 ChannelOutboundHandler 中传播,最后到达客户端。