Netty架构分析

1.逻辑架构

Netty逻辑架构图

逻辑架构

  • 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的二进制类库即可实现协议的扩展和定制

results matching ""

    No results matching ""