Netty架构分析
1.逻辑架构

逻辑架构
- Reactor通信调度层
- 它由一系列辅助类完成,包括Reactor线程NioEventLoop以及其父类、NioSocketChannel/NioServerSocketChannel以及其父类、ByteBuffer以及由其衍生出来的各种Buffer、Unsafe以及其衍生出的各种内部类等
- 主要职责就是监听网络的读写和连接操作,负责将网络层的数据读取到内存缓冲区中,然后触发各种网络事件,例如连接创建、连接激活、读事件、写事件等等,将这些事件触发到PipeLine中,由PipeLine充当的职责链来进行后续的处理
- 职责链PipeLine
- 负责事件在职责链中的有序传播,同时负责动态的编排职责链,职责链可以选择监听和处理自己关心的事件,它可以拦截处理和向后/向前传播事件,不同的应用的Handler节点的功能也不同,通常情况下,往往会开发编解码Hanlder用于消息的编解码,它可以将外部的协议消息转换成内部的POJO对象,这样上层业务侧只需要关心处理业务逻辑即可,不需要感知底层的协议差异和线程模型差异,实现了架构层面的分层隔离
- 业务逻辑处理层,可以分为两类
- 纯粹的业务逻辑
- 应用层协议管理,例如HTTP协议、FTP协议等
2.关键架构质量属性
2.1 高性能
Netty的架构设计是如何实现高性能的?
- 采用异步非阻塞的I/O类库, 基于Reactor模式实现,解决了传统同步阻塞I/O模式下一个服务端无法平滑地处理线性增长的客户端的问题
- TCP接收和发送缓冲区使用直接内存代替堆内存,避免了内存复制,提升了I/O读取和写入的性能
- 支持通过内存池的方式循环利用ByteBuf, 避免了频繁创建和销毁ByteBuf带来的性能损耗
- 可配置的I/O线程数、TCP参数等,为不同的用户场景提供定制化的调优参数,满足不同的性能场景
- 采用环形数组缓冲区实现无锁化并发编程,代替传统的线程安全容器或者锁
- 合理地使用线程安全容器、原子类,提升系统的并发处理能力
- 关键资源的处理使用单线程串行化的方式,避免多线程并发访问带来的锁竞争和额外的CPU资源消耗问题
- 通过引用计数器及时地申请释放不再被引用的对象,细粒度的内存管理降低了GC的频率,减少了频繁GC带来的时延增大和CPU损耗
2.2.2 可靠性
可靠性挑战
- 作为RPC框架的基础网络通信框架,一旦故障将导致无法进行远程服务(接口)调用
- 作为应用层协议的基础通信框架,一旦故障将导致应用协议栈无法正常工作
- 网络环境复杂(例如推送服务的GSM/3G/WIFI网络),故障不可避免,业务却不能中断
心跳检测机制分为三个层面
- TCP层面的心跳检测,即TCP的Keep-Alive机制,它的作用域是整个TCP协议栈
- 协议层的心跳检测,主要存在于长连接协议中.例如SMPP协议
- 应用层的心跳检测,它主要由各业务产品通过约定方式定时给对方发送心跳消息实现
Keep-Alive仅仅是TCP协议层会发送连通性检测包,但并不代表设置了Keep-Alive就是长连接了
Netty提供的心跳检测机制
- 读空闲,链路持续时间t没有读取到任何消息
- 写空闲,链路持续时间t没有发送任何消息
- 读写空闲,链路持续时间t没有接收或者发送任何消息(netty自带心跳处理Handler IdleStateHandler)
2.2.3 优雅退出

2.3 可定制性
Netty的可定制性
- 责任链模式:ChannelPipeline基于责任链模式开发,便于业务逻辑的拦截、定制和扩展.
- 基于接口的开发:关键的类库都提供了接口或者抽象类,如果Netty自身的实现无法满足用户的需求,可以由用户自定义实现相关接口
- 提供了大量工厂类,通过重载这些工厂类可以按需创建出用户实现的对象
- 提供了大量的系统参数供用户按需设置,增强系统的场景定制性
2.4 可扩展性
基于Netty的基础NIO框架,可以方便地进行应用层协议定制,例如HTTP协议栈、Thrift协议栈、FTP协议栈等.这些扩展不需要修改Netty的源码,直接基于Netty的二进制类库即可实现协议的扩展和定制