Netty 权威指南笔记(四):架构剖析

Netty 权威指南笔记(四):架构剖析

对 Netty 的架构进行剖析,学习其设计,便于在今后的架构设计中,设计出高性能、高可靠、可扩展的产品。

Netty 逻辑架构

Netty 采用了典型的三层网络架构进行设计和开发,其逻辑架构如下图所示:

Netty 逻辑架构图

  1. Reactor 通信调度层:由一系列辅助类组成,包括 Reactor 线程 NioEventLoop 及其父类,NioSocketChannel 和 NioServerSocketChannel 等等。该层的职责就是监听网络的读写和连接操作,负责将网络层的数据读到内存缓冲区,然后触发各自网络事件,例如连接创建、连接激活、读事件、写事件等。将这些事件触发到 pipeline 中,由 pipeline 管理的职责链来进行后续的处理。
  2. 职责链 ChannelPipeline:负责事件在职责链中的有序传播,以及负责动态地编排职责链。职责链可以选择监听和处理自己关心的事件,拦截处理和向后传播事件。
  3. 业务逻辑编排层:业务逻辑编排层通常有两类,一类是纯粹的业务逻辑编排,一类是应用层协议插件,用于特定协议相关的会话和链路管理。由于应用层协议栈往往是开发一次到处运行,并且变动较小,故而将应用协议到 POJO 的转变和上层业务放到不同的 ChannelHandler 中,就可以实现协议层和业务逻辑层的隔离,实现架构层面的分层隔离。

关键架构质量属性

Netty 是一个高性能的、高可靠的、可扩展的异步通信框架,那么高性能、高可靠、可扩展设计体现在哪里呢?

高性能

性能是设计出来的,而不是测试出来的。那么,Netty 的架构设计是如何实现高性能的呢?

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

高可靠

  1. 链路有效性检测:由于长连接不需要每次发送消息都创建链路,也不需要在消息完成交互时关闭链路,因此相对于短连接性能更高。为了保证长连接的链路有效性,往往需要通过心跳机制周期性地进行链路检测。使用心跳机制的原因是,避免在系统空闲时因网络闪断而断开连接,之后又遇到海量业务冲击导致消息积压无法处理。为了解决这个问题,需要周期性地对链路进行有效性检测,一旦发现问题,可以及时关闭链路,重建 TCP 连接。为了支持心跳,Netty 提供了两种链路空闲检测机制:
    • 读空闲超时机制:连续 T 周期没有消息可读时,发送心跳消息,进行链路检测。如果连续 N 个周期没有读取到心跳消息,可以主动关闭链路,重建连接。
    • 写空闲超时机制:连续 T 周期没有消息需要发送时,发送心跳消息,进行链路检测。如果连续 N 个周期没有读取对方发回的心跳消息,可以主动关闭链路,重建连接。
  2. 内存保护机制:Netty 提供多种机制对内存进行保护,包括以下几个方面:
    • 通过对象引用计数器对 ByteBuf 进行细粒度的内存申请和释放,对非法的对象引用进行检测和保护。
    • 可设置的内存容量上限,包括 ByteBuf、线程池线程数等,避免异常请求耗光内存。
  3. 优雅停机:优雅停机功能指的是当系统推出时,JVM 通过注册的 Shutdown Hook 拦截到退出信号量,然后执行推出操作,释放相关模块的资源占用,将缓冲区的消息处理完成或清空,将待刷新的数据持久化到磁盘和数据库中,等到资源回收和缓冲区消息处理完成之后,再退出。

可定制、易扩展

  1. 责任链模式:ChannelPipeline 基于责任链模式开发,便于业务逻辑的拦截、定制和扩展。
  2. 基于接口的开发:关键的类库都提供了接口或抽象类,便于用户自定义实现。
  3. 提供大量的工厂类,通过重载这些工厂类,可以按需创建出用户需要的对象。
  4. 提供大量系统参数供用户按需设置,增强系统的场景定制性。

总结,是为了强化学习效果。

Netty5.0 架构剖析和源码解读 作者:李林锋 版权所有 email neu_lilinfeng@ © Netty5.0 架构剖析和源码解读1 1. 概述2 1.1. JAVA 的IO演进2 1.1.1. 传统BIO通信的弊端2 1.1.2. Linux 的网络IO模型简介4 1.1.3. IO复用技术介绍7 1.1.4. JAVA的异步IO8 1.1.5. 业界主流的NIO框架介绍10 2.NIO入门10 2.1. NIO服务端10 2.2. NIO客户端13 3.Netty源码分析16 3.1. 服务端创建16 3.1.1. 服务端启动辅助类ServerBootstrap16 3.1.2. NioServerSocketChannel 的注册21 3.1.3. 新的客户端接入25 3.2. 客户端创建28 3.2.1. 客户端连接辅助类Bootstrap28 3.2.2. 服务端返回ACK应答,客户端连接成功32 3.3. 读操作33 3.3.1. 异步读取消息33 3.4. 写操作39 3.4.1. 异步消息发送39 3.4.2. Flush操作42 4.Netty架构50 4.1. 逻辑架构50 5. 附录51 5.1. 作者简介51 5.2. 使用声明51 1. 概述 1.1.JAVA 的IO演进 1.1.1. 传统BIO通信的弊端 在JDK 1.4推出JAVANIO1.0之前,基于JAVA 的所有Socket通信都采用 BIO 了同步阻塞模式( ),这种一请求一应答的通信模型简化了上层的应用开发, 但是在可靠性和性能方面存在巨大的弊端。所以,在很长一段时间,大型的应 C C++ 用服务器都采用 或者 开发。当并发访问量增大、响应时间延迟变大后, 采用JAVABIO作为服务端的软件只有通过硬件不断的扩容来满足访问量的激 增,它大大增加了企业的成本,随着集群的膨胀,系统的可维护性也面临巨大 的挑战,解决这个问题已经刻不容缓。 首先,我们通过下面这幅图来看下采用BIO 的服务端通信模型:采用BIO 通信模型的 1connect NewThread1 WebBrowse 2connect 2handle(Req) WebBrowse 3connect Acceptor NewThread2 WebBrowse WebBrowse 4connect NewThread3 3sendResponsetopeer NewThread4 图1.1.1-1 BIO通信模型图 服务端,通常由一个独立的Accepto 线程负责监听客户端的连接,接收到客户 端连接之后为客户端连接创建一个新的线程处理请求消息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值