Netty 核心组件
1. 前言
本节我们主要从整体上了解 Netty 有哪些核心组件,很多同学学习完 Netty 虽然会使用,但是只知道如何自定义 Handler 而已,根本不清楚 Netty 有哪些核心的组件。
本节的主要目的是,从整体上概括 Netty 的核心组件,有助于深入了解 Netty 以及关于 Netty 的面试。
2. 核心组件
Netty 的核心模块组件主要分为以下:
组件模块 | 说明 |
---|---|
Boostrap | Bootstrap 其实就是启动的意思,主要用来配置 Netty 的相关配置,串联各个组件,针对客户端。 |
ServerBootstrap | 同上,只是它是针对服务端。 |
线程模型 | 了解 Reactor 线程模型。 |
EventLoopGroup | 是一组 EventLoop 的抽象,可以简单理解就是线程池,一般分为 BossEventLoopGroup 和 WorkerEventLoopGroup。 |
ChannelFuture | Netty 的所有 IO 操作都是异步的,通过注册监听器来监听执行结果的返回。 |
Channel | Netty 的网络通信组件,客户端和服务端建立连接之后会维持一个 Channel。 |
ChannelHandlerContext | 保存 Channel 对于的上下文,同时关联一个 ChannelHandler 对象。 |
ChannelHandler | 自定义业务 Handler 需要实现它或它的子类,提供了一套生命周期的方法。 |
ChannelPipeline | ChannelPipeline 可认为是一个管道,是管理业务 Handler,通俗理解是保存 ChannelHandler 的 List 集合。 |
ByteBuf | ByteBuf 是一个字节容器,提供了常见 api。Netty 是面向 ByteBuf 来传输数据的。 |
编码和解码 | Netty 内置了常见编解码器,我们也可以自定义自己的编解码器。并且可以把编解码器封装成独立的 Handler,简化繁琐的流程。 |
拆包和粘包问题 | 了解为什么会出现拆包和粘包问题,如何去解决它,以及 Netty 内置了常见的拆包器。 |
总结,以上组件(或者知识点)是 Netty 知识体系里面的核心,并且也是面试当中经常问的内容,有的只需要配置一下即可,很少需要我们去管(如:EventLoopGroup);有的需要我们去自定义扩展。
核心组件架构图:
在真实开发当中,需要我们去解决的问题,主要如下:
- 使用 ChannelPipeline 管理自定义 ChannelHandler;
- 业务实体和 ByteBuf 之间的转换;
- 借助第三方序列化技术、自定义通信协议规则、反射等,自定义编码和解码器,使用通用实体;
- 如何解决拆包和粘包问题,其发生的原因是什么,如果解决。
3. 组件详解
Netty 的它优势在于,它是配置化的开发,仅仅靠简单的配置,背后就能实现很复杂的逻辑。但是通常情况下我们很难去了解其背后的原理。下面我们主要挑选开发当中比较常见的组件进行讲解。
3.1 ChannelHandler
ChannelHandler 是一个接口,处理 IO 事件,可以简单的理解它是一个链表当中的一个节点,它的 UML 图如下所示:
ChannelHandler 架构图说明:
- ChannelHandler 两个子接口,分别是 ChannelInboundHandler 和 ChannelOutboundHandler;其中 ChannelInboundHandler 主要用于处理入站的 I/O 事件;ChannelOutboundHandler 用于处理出站的 I/O 事件;
- ChannelInboundHandler 的实现类 ChannelInboundHandlerAdapter 处理入站 I/O 事件;
- ChannelOutboundHandler 的实现类 ChannelOutboundHandlerAdapter 处理出站 I/O 事件;
在开发当中,ChannelInboundHandlerAdapter
是使用最多的,其它很少直接使用。值得注意的是 I/O 入站和出站的执行顺序,这个跟 SpringMVC 的拦截器的执行顺序一样。
3.2. ChannelPipeline
ChannelPipeline 是一个比较核心的知识点,它底层设计是采用责任链设计模式,主要作用是管理 Handler 双向链表,包括入站和出站,主要是拦截 inboud 和 outbound 事件,然后每个 handler 节点负责处理具体逻辑。
关系梳理:
- 一个客户端对应一个 Channel;
- 一个 Channel 对应一个 ChannelPipeline;
- 一个 ChannelPipeline 又维护了一个双向链表,其中链表的节点是
ChannelHandlerContext
; - 一个
ChannelHandlerContext
则关联一个ChannelHandler
(自定义 Handler); - ChannelHandler 则是自定义 Handler 的一个顶级抽象接口。
入站和出站的顺序:
- 入站: 事件会从链表的头部一直往后执行,
ChannelInboundHandlerAdapter
子类会被触发; - 出站: 事件会从链表的尾部一直往前执行,
ChannelOutboundHandlerAdapter
子类会被触发。
4. 小结
本节内容,主要让大家从整体上了解 Netty 有哪些核心的组件构成,每个主要的作用是什么,主要是方便后面章节深入学习。其中,核心掌握 ChannelHandler 和 ChannelPipeline 这两个组件,平时开发当中涉及比较多的就是这两个组件。
- 掌握 ChannelHandler 的 UML 架构关系;
- 掌握入站和出站分别继承 ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter;
- 掌握 ChannelPipeline 和 ChannelHandler 之间的关系;
- 掌握入站和出站的执行顺序。