Netty基础
Netty基础
- 一级目录
- I/O请求基础知识
- Netty如何实现自己的I/O模型
- 网络框架的选型
- Netty整体架构
- Netty逻辑处理架构
- 网络通信层
- 事件调度层
- 服务编排层
- 组件关系梳理
- Netty源码结构
netty是目前最流行的一款高性能java网络编程框架,广泛使用于中间件、直播、社交、游戏等领域。
是Dubbo、RocketMQ、Elasticsearch、Hbase等
netty的高性能表现在哪些方面?
netty中有哪些重要组件,他们之间的联系
netty的内存池、对象池是如何设计的
针对netty有哪些印象深刻的系统调优案例
一级目录
netty对于:数据编解码、拆包/粘包、TCP断线重连
提供了现成的解决方案
遇到问题可以在社区讨论
netty的迭代周期短修复问题快
可靠性和健壮性
为什么选择netty
I/O模型、线程模型和事件处理机制
易用性API接口
对数据协议、序列化的支持
I/O请求基础知识
- I/O调用阶段:用户进程向内核发起系统调用
- I/O执行阶段:内核等待I/O请求处理完成返回
Linux的五种I/O模式
-
同步阻塞I/O(BIO)
-
同步非阻塞I/O(NIO)
-
I/O多路复用
-
信号驱动I/O
-
异步I/O
Netty如何实现自己的I/O模型
基于非阻塞I/O实现
底层依赖的是JDK NIO框架的多路复用器Selector
一个多路复用器Selector可以同时轮询多个Channel
在I/O多路复用的场景下,当有数据处于就绪状态后,需要一个事件分发器(Event Dispather)
负责将读写事件分发给对应的读写事件处理器(Event Handler)
事件分发器有两种设计模式
Reactor(采用同步I/O)和Proactor(采用异步I/O)
netty采用主从reactor多线程模型,所有的I/O事件都注册到一个I/O多路复用器上,当有I/O事件就绪后I/O多路复用器会将该I/O事件通过事件分发器,分发到对应的事件处理器中,该线程模型避免了同步问题以及多线程切换带来的资源开销,真正做到高性能低延迟
更低的资源消耗:
面临大量的网络对象创建和销毁的问题
- 对象池复用技术
- 零拷贝技术
网络框架的选型
Netty整体架构
主要分为三个模块:
Core核心层
提供底层网络通信的通用抽象和实现,包括可扩展的事件模型、通用的通信API、支持零拷贝的ByteBuf等
Protocol Support 协议支持层
覆盖了主流协议的编解码实现,如HTTP、SSL、Protobuf、压缩、大文件传输、WebSocket、文本、二进制等
支持自定义应用层协议
TransportService传输服务层
传输服务层提供了网络传输能力的定义和实现方法,支持Socket、HTTP隧道、虚拟机管道等传输方式
netty的模块设计具有较高的通用性和可扩展性
Netty逻辑处理架构
网络通信层
职责是执行网络I/O的操作,支持多种网络协议和I/O模型的连接操作
事件调度层
通过Reactor线程模型对各类事件进行聚合处理
通过Selector主循环线程集成多种事件
核心组件包括EventLoopGroup、EventLoop
eventLoopGroup本质是一个线程池,主要负责接收I/O请求,并分配线程执行处理请求
- 一个eventLoopGroup往往包含一个或多个EventLoop,EventLoop用于处理channel生命周期内的所有I/O事件,如accept、read、write等等
- EventLoop同一个时间会与一个线程绑定,每个EventLoop负责处理多个channel
- 每新建一个channel,EventLoopGroup会选择一个EventLoop与其绑定,该channel在生命周期内都可以对eventLoop进行多次绑定和解绑
EventLoopGroup是Netty Reactor线程模型的具体实现方式
事件调度层负责监听网络连接和读写操作,然后触发各种类型的网络事件,需要一种机制管理这种错综复杂的事件,并有序地执行
服务编排层
负责组装各类服务,用以实现网络事件的动态编排和有序传播
ChannelPipeline负责组装各种ChannelHandler
实际数据的编解码以及加工处理操作由ChannelHandler完成
当I/O读写事件触发时,ChannelPipeline会依次调用ChannelHandle列表对Channel的数据进行拦截和处理
ChannelPipeline是线程安全的,因为每一个新的Channel会对应绑定一个新的ChannelPipeline
一个ChannelPipeline关联一个EventLoop,一个EventLoop仅会绑定一个线程
以客户端为例:数据从客户端发往服务端,该过程称为出站,反之为入站
数据入站有一系列InboundHandler处理,再以一系列相反方向的outboundHandler处理后完成出站,我们经常使用的编码encoder是编码操作,解码decoder是入站操作
服务端接收到客户端数据后,需要先经过decoder入站处理后,再通过encoder出站通知客户端
每创建一个Channel都会绑定一个新的ChannelPipeline;
ChannelPIpeline中每加入一个ChannelHandler都会绑定一个ChannelHandleContext
每个Handler绑定Context的作用是什么?
- context 用于保存ChannelHandler上下文,通过它可以知道ChannelPipeline和ChannelHandler的关联关系
- context实现了ChannelHandler之间的交互
- context包含了ChannelHandler生命周期的所有事件,如connect、bind、read、flush、write、close等
组件关系梳理
Netty源码结构