Netty : 大纲及笔记
一 . 前言
文档目的 :
- 大纲型文档 , 持续更新
- 梳理 Netty 的主要概念
- 梳理 Netty 的核心类
- 对 Netty 主要结构有一个基础的认知
后续会进行深入的源码分析 , 作为一个快查手册 ,将会逐步完善该文档
1.1 概念
Netty 是一个基于 JAVA NIO 类库的异步通信框架,用于创建异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性的网络客户端和服务器端
下面依次对这些概念做一个解析 :
// JAVA NIO 类库
通过 Selector 实现的基于缓冲区 (Buffer) 的非阻塞式 IO
详情可以参考这一篇文章 : https://juejin.cn/post/6988884927525683230
// 异步通信框架
异步是由于 NIO 模型 , 通信说明了 Netty 的实质, 这是一个用于多端通信的框架
// 基于事件驱动
Netty 中是针对网络事件来处理的 , 这种模式类似于策略模式
// 高性能
Netty 的性能极其优异 , 很多框架的底层都是通过 Netty 来实现 , 高性能的一大原因是得益于 NIO 的无阻塞 IO , 使其支持高并发的场景
// 高可定制
Netty 提供了很多现成的使用类 ,但是同时他可以通过实现接口来扩展功能 , 来适应多种业务场景
Netty 除了支持 HTTP ,WebSocket 等常见协议的开发 ,同时支持私有协议的开发
// 网络客户端端服务器
Netty 需要构建 Client 端和 Server 端来构建网络通信功能
1.2 Netty 模型
Netty 的线程模型是基于 Reactor 模式的一个实现 , 那么就首先要了解什么是 Reactor .
I/O 多路复用模式通常有2种实现 :
- Reactor : 采用同步IO
- Proactor : 采用异步IO
在Reactor中,当读写操作准备就绪后 ,将会就绪事件传递给对应的处理器,最后由处理器负责完成实际的读写工作
Reactor 中有三种线程模型 :
- 单线程模型 : 所有的IO操作都在同一个NIO线程上面完成
- 多线程模型 : 有一组NIO线程处理IO操作
- 主从多线程模型 : 服务端用于接收客户端连接的不再是个1个单独的NIO线程,而是一个独立的NIO线程池
PS : 注意 , Netty 采用的是主从多线程模型 , 这个后面再专门深入
主从多线程的角色 :
- Main Reactor : 主要负责连接事件,并将IO读写请求转发到 SubReactor 线程池
- Acceptor : 不真正负责连接请求的建立,而只将其请求委托 Main Reactor 线程池来实现 , 类似于转发器
- Sub Reactor : Main Reactor将通道的读写转发到 Sub Reactor 线程池中一个线程(负载均衡),负责数据的读写
主从多线程主要流程 :
- MainReactor 监听 Server Socket
- 客户端连接 (OP_ACCEPT 事件)
- MainReactor 将通道的读写转发给 Sub Reactor
- 创建 NioSocketChannel对象 , 从SubReactor内挑选一个线程 , 发起 OP_READ事件
- 服务端通过 NioSocketChannel 从网卡中读取数据
后面的具体流程这一篇就不深入了
1.3 Netty 的功能特点
- 异步、非阻塞、基于事件驱动的NIO框架
- 支持多种传输层通信协议,包括TCP、UDP等
- 开发异步HTTP服务端和客户端应用程序
- 提供对多种应用层协议的支持,包括TCP私有协议、HTTP协议、WebSocket协议、文件传输等
- 默认提供多种编解码能力,包括Java序列化、Google的ProtoBuf、二进制编解码、Jboss marshalling、文本字符串、base64、简单XML等,这些编解码框架可以被用户直接使用
- 提供形式多样的编解码基础类库,可以非常方便的实现私有协议栈编解码框架的二次定制和开发
- 经典的ChannelFuture-listener机制,所有的异步IO操作都可以设置listener进行监听和获取操作结果
- 基于ChannelPipeline-ChannelHandler的责任链模式,可以方便的自定义业务拦截器用于业务逻辑定制
- 安全性:支持SSL、HTTPS
- 可靠性:流量整形、读写超时控制机制、缓冲区最大容量限制、资源的优雅释放等
- 简洁的API和启动辅助类,简化开发难度,减少代码量
Netty 中的常见事件
Netty 使用事件驱动的应用程序范例,因此数据处理 pipeline 是经过处理程序的事件链 , 入站事件可以是 :
- Channel activation and deactivation 通道激活和失活
- Read operation events 阅读操作事件
- Exception events 异常事件
- User events 用户事件
1.4 业务分层
第一层 : Reactor 通信调度层
由一系列辅助类组成,包括 Reactor 线程NioEventLoop 以及其父类、NioSocketChannel/NioServerSocketChannel 以及其父类、ByteBuffer 以及由其衍生出来的各种 Buffer、Unsafe 以及其衍生出的各种内部子类等
第二层 :职责链 ChannelPipeLine
负责调度事件在职责链中的传播,支持动态的编排职责链,职责链可以选择性的拦截自己关心的事件,对于其它IO操作和事件忽略,Handler同时支持inbound和outbound事件
第三层 : 业务逻辑编排层
业务逻辑编排层通常有两类:一类是纯粹的业务逻辑编排,还有一类是应用层协议插件,用于协议相关的编解码和链路管理,例如 CMPP 协议插件
1.5 项目结构
- common : 通用的工具类项目
- buffer : 对应 Zero-Copy-Capable Rich Byte Buffer , 自行实现的一个 Byte Buffer 字节缓冲区
- transport : 主要是 Transport Services、Universal Communication API 和 Extensible Event Model , 该项目是网络传输通道的抽象和实现
- codec : 对应 Protocol Support , 该项目是协议编解码的抽象与部分实现
- handler : 该项目是提供内置的连接通道处理器( ChannelHandler )实现类
- example : 该项目是提供各种 Netty 使用示例
1.6 功能特点
零拷贝
零拷贝 : CPU不需要为数据在内存之间的拷贝消耗资源 ,不需要将文件内容拷贝到用户空间ÿ