Netty-13 Netty架构

一、Netty架构

Netty采用了三层网络架构进行设计和开发,架构图如下:
在这里插入图片描述

(一)Reactor通信调度层

Netty的最底层是Reactor通信调度层,它通过一系列的辅助类,包括Reactor线程NioEventLoop及其父类。NioSocketChannel、NIOServerSocketChannel及其父类。ByteBuffer及其衍生出来的各种Buffer,UnSafe及其衍生的各种内部类等等。该层的主要职责就是监听网络的读写和连接操作,负责将网络层的数据读取到内存缓冲区,然后出发各种事件,如创建链路、读写事件等等。将这些事件触发到PipeLine中,由PipeLine管理的职责连进行后续的处理。

(二)职责链ChannelPipeline

它负责事件在职责链中的有序传播,同时负责动态的编排职责链,职责连可以选择和监听自己关心的事件。它负责拦截处理和向后/前传播事件。通常情况下,Handler大概有两类,一类是负责把协议消息和POJO对象进行相互转换的,一类是进行纯粹的业务编码的。

(三)业务逻辑层(Service Handler)

业务逻辑层通常有两类:一类是纯粹的业务逻辑编排;一类是其他的应用层协议插件,如CMPP协议,用于管理和中国移动短信系统的对接。

二、 Netty架构的特点

(一)高性能

影响产品性能的因素:

  1. 架构不合理;
  2. 编码实现不合理,如死锁等;
  3. 服务器硬件配置太低;
  4. 带宽、磁盘IOPS等导致的I/O性能;

Netty基于以下方案实现了高性能:

  1. 采用异步非阻塞的I/O类库,基于Reactor模型实现,解决了BIO模式下一个服务器无法平滑的处理客户端数量线性增长的问题;
  2. TCP接受和发送缓冲区使用直接内存代替堆内存,避免了内存复制,提高了I/O读取和写入的性能;
  3. 支持通过内存池的方式循环利用ByteBuf,避免了频繁创建和销毁ByteBuf带来的性能损耗;
  4. 可配置的I/O线程数、TCP参数等,为不同的场景提供不同的定制化方案,满足不能的性能场景。
  5. 采用环形缓冲区实现无锁化并发编程,代替传统的线程安全器或者锁;
  6. 合理的使用线程安全器、原子类等,提高系统的并发能力;
  7. 关键资源的处理使用单线程串行模式,避免因为多线程造成的锁竞争和额外的CPU消耗;
  8. 通过引用计数器及时的申请释放不再需要使用的资源,降低GC频率。

(二)可靠性

  1. 链路有效性监测
  • 由于长链接不需要每次发送消息都建立连接,也不用完成之后关闭链路,所以性能上比短连接要高。
  • 为了保证长链接的有效性,往往需要通过心跳机制周期性的进行链路监测。当链路没有消息传送的时候,如果链路被关闭了,等到有业务的时候,需要进行重连,影响性能。通过心跳机制,一旦发现断开,进行重连。
  • Netty有两种链路空闲监测机制:
    a. 读空闲超时机制:当连续周期T没有消息要发送时,触发超时Handler。用户可以通过读空闲超时心跳消息,进行链路检测。如果连续N个周期仍然没有读取到心跳信息,可以主动关闭链路。
    b.写空闲超时机制:当连续周期T没有消息可读时,触发超时Handler。用户可以通过读空闲超时心跳消息,进行链路检测。如果连续N个周期仍然没有接受到对方心跳信息,可以主动关闭链路。
  1. 内存保护机制
    Netty通过多个方面对内存进行保护。
  • 通过对象引用计数器对ByteBuf等内置对象进行细粒度的申请和释放;
  • 通过内存池重用ByteBuf,节省内存;
  • 可设置的内存容量上限,包括ByteBuf、线程池数量等。通过设置单个ByteBuf的最大长度,可以限制解码错位发生的码流过长问题。
  1. 优雅停机
    Netty提供了一些方法用于优雅的退出系统,当系统退出的时候,JVM通过注册的Shutdown Hook拦截到退出信号量,从而执行退出操作,释放相关的资源。如:
  • EventExecutorGroup.shutdownGracefully
  • Unsafe.close

(三)可定制性

Netty的可定制性主要取决于以下几点:

  1. 责任链模式:ChannelPipeline基于责任链模式开发,便于业务逻辑的拦截、定制和扩展;
  2. 基于接口的开发:关键的类库都提供了接口和抽象类,当Netty自身实现无法满足要求的时候,用户可以自己去进行扩展;
  3. 提供了大量工厂类,通过重载这些工厂类,可以按需创建出用户实现的对象;

(四)可扩展性

基于Netty协议可以方便的进行应用层协议定制,如HTTP协议、FTP协议等等。这些协议不需要修改netty源码,只需要基于Netty的二进制类库即可实现。

猜你喜欢

转载自blog.csdn.net/mail_liuxing/article/details/91381431
今日推荐