Netty高性能网络框架(一)

简介: Netty高性能网络框架(一)

NIO

一、NIO通信模型(默认为同步非阻塞)

1、NIO本来是同步的非阻塞的,通过Netty的包装变成了异步的非阻塞框架。上面的图是同步非阻塞的,当数据没有准备好的时候,系统会一直在轮询的等待,对于用户的请求是非阻塞,实际上不是完全的非阻塞。当我们得到一个多路复用选择器的时候,需要打开它,然后把事件注册到多路复用的选择器上去。多路复用的巧妙的技术是不断在轮询,轮询的事件的变化。一旦连接成功之后,就一直轮询读和写的事件,就不会重新在连接的事件了。一个channel只对应一个事件。

2、如果原来用BIO的时候,多个请求对应多个线程,现在是所有的请求对应服务端的一个线程。这种情况针对小项目是没有多大的影响,在整体的过程中,有可能线程是空闲的。

现在是多个请求通过通道到多路复用的选择器上。

Thread不停的轮询去处理请求,这就节省了线程对时间片的占用时间,和cpu处理效率的问题。

NIO的服务端的通信序列图:Reactor Thread:线程堆,用来生成多路复用选择器

在netty中是把第六步做成了异步的处理。否则是阻塞的,IO事件都交给系统去处理了。所以不会阻塞的。这就是netty在nio中第6步做了改善。


NIO客户端的通信序列图


1. 背景

1.1. 惊人的性能数据

1、通过使用 Netty4 + Thrift 压缩二进制编解码技术,他们实现了 10W TPS(每秒的事务处理量),的跨节点远程服务调用。相比于传统基于 Java 序列化 +BIO(同步阻塞 IO)的通信框架,性能提升了 8 倍多。精心的设计 Reactor 线程模型,达到上述性能指标是完全有可能的,Reactor就是反应堆的线程模型。

1.2. Netty 基础入门

1、Netty 是一个高性能、异步事件驱动的 NIO 框架,它提供了对 TCP、UDP 和文件传输的支持,作为一个异步 NIO 框架,Netty 的所有 IO 操作都是异步非阻塞的,通过 Future-Listener 机制,用户可以方便的主动获取或者通过通知机制获得 IO 操作结果。

2、作为当前最流行的 NIO 框架,Netty 在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,一些业界著名的开源组件也基于 Netty 的 NIO 框架构建。在zk和dubbo中都有netty。

2. Netty高效的 Reactor 线程模型

常用的 Reactor 线程模型有三种,分别如下:

1) Reactor(反应堆) 单线程模型;

2) Reactor 多线程模型;

3) 主从 Reactor 多线程模型

Reactor 单线程模型,指的是所有的 IO 操作都在同一个 NIO 线程上面完成,NIO 线程的职责如下:

1) 作为 NIO 服务端,接收客户端的 TCP 连接;

2) 作为 NIO 客户端,向服务端发起 TCP 连接;

3) 读取通信对端的请求或者应答消息(用这个特性可以做web服务器)

4) 向通信对端发送消息请求或者应答消息。

2.1 Reactor 单线程模型

Reactor 单线程模型示意图如下所示:

由于 Reactor 模式使用的是异步非阻塞 IO,所有的 IO 操作都不会导致阻塞,理论上一个线程可以独立处理所有 IO 相关的操作。从架构层面看,一个 NIO 线程确实可以完成其承担的职责。例如,通过 Acceptor 接收客户端的 TCP 连接请求消息,链路建立成功之后,通过 Dispatch 将对应的 ByteBuffer 派发到指定的 Handler 上进行消息解码。用户 Handler 可以通过 NIO 线程将消息发送给客户端。

对于一些小容量应用场景,可以使用单线程模型。但是对于高负载、大并发的应用却不合适,主要原因如下:

1) 一个 NIO 线程同时处理成百上千的链路,性能上无法支撑,即便 NIO 线程的 CPU 负荷达到 100%,也无法满足海量消息的编码、解码、读取和发送;

2) 当 NIO 线程负载过重之后,处理速度将变慢,这会导致大量客户端连接超时,超时之后往往会进行重发,这更加重了 NIO 线程的负载,最终会导致大量消息积压和处理超时,NIO 线程会成为系统的性能瓶颈;

3) 可靠性问题:一旦 NIO 线程意外跑飞,或者进入死循环,会导致整个系统通信模块不可用,不能接收和处理外部消息,造成节点故障。

2.2 Rector 多线程模型

为了解决这些问题,演进出了 Reactor 多线程模型。

Rector 多线程模型与单线程模型最大的区别就是有一组 NIO 线程处理 IO 操作,它的原理图如下:

Reactor 多线程模型的特点:

1) 有专门一个 NIO 线程 -Acceptor 线程用于监听服务端,接收客户端的 TCP 连接请求;

2) 网络 IO 操作 - 读、写等由一个 NIO 线程池负责,线程池可以采用标准的 JDK 线程池实现,它包含一个任务队列和 N 个可用的线程,由这些 NIO 线程负责消息的读取、解码、编码和发送;

3) 1 个 NIO 线程可以同时处理 N 条链路,但是 1 个链路只对应 1 个 NIO 线程,防止发生并发操作问题

2.3 主从 Reactor 线程模型(推荐使用)

在绝大多数场景下,Reactor 多线程模型都可以满足性能需求;但是,在极特殊应用场景中,一个 NIO 线程负责监听和处理所有的客户端连接可能会存在性能问题。例如百万客户端并发连接,或者服务端需要对客户端的握手消息进行安全认证,认证本身非常损耗性能。在这类场景下,单独一个 Acceptor 线程可能会存在性能不足问题,为了解决性能问题,产生了第三种 Reactor 线程模型 - 主从 Reactor 多线程模型。

主从 Reactor 线程模型的特点是:服务端用于接收客户端连接的不再是个 1 个单独的 NIO 线程,而是一个独立的 NIO 线程池。Acceptor 接收到客户端 TCP 连接请求处理完成后(可能包含接入认证等),将新创建的 SocketChannel 注册到 IO 线程池(sub reactor 线程池)的某个 IO 线程上,由它负责 SocketChannel 的读写和编解码工作。Acceptor 线程池仅仅只用于客户端的登陆、握手和安全认证,一旦链路建立成功,就将链路注册到后端 subReactor 线程池的 IO 线程上,由 IO 线程负责后续的 IO 操作。

它的线程模型如下图所示:

利用主从 NIO 线程模型,可以解决 1 个服务端监听线程无法有效处理所有客户端连接的性能不足问题。因此,在 Netty 的官方 demo 中,推荐使用该线程模型。

事实上,Netty 的线程模型并非固定不变,通过在启动辅助类中创建不同的 EventLoopGroup (事件循环组)实例并通过适当的参数配置,就可以支持上述三种 Reactor 线程模型。正是因为 Netty 对 Reactor 线程模型的支持提供了灵活的定制能力,所以可以满足不同业务场景的性能诉求。

3. 无锁化的串行设计理念(解决并发)

1、在大多数场景下,并行多线程处理可以提升系统的并发性能。但是,如果对于共享资源的并发访问处理不当,会带来严重的锁竞争,这最终会导致性能的下降。为了尽可能的避免锁竞争带来的性能损耗,可以通过串行化设计,即消息的处理尽可能在同一个线程内完成,期间不进行线程切换,这样就避免了多线程竞争和同步锁。

2、为了尽可能提升性能,Netty 采用了串行无锁化设计,在 IO 线程内部进行串行操作,避免多线程竞争导致的性能下降。表面上看,串行化设计似乎 CPU 利用率不高,并发程度不够。但是,通过调整 NIO 线程池的线程参数,可以同时启动多个串行化的线程并行运行,这种局部无锁化的串行线程设计相比一个队列 - 多个工作线程模型性能更优,来源于无锁化编程设计

Netty 的串行化设计工作原理图如下:

3、Netty 的NioEventLoop 读取到消息之后,直接调用 ChannelPipeline(管道) 的 fireChannelRead(Object msg),只要用户不主动切换线程,一直会由 NioEventLoop 调用到用户的 Handler,期间不进行线程切换,这种串行化处理方式避免了多线程操作导致的锁的竞争,从性能角度看是最优的。在netty中可以创建多个事件循环组来并行的去执行。所以这样也能够并发性能。netty5比netty4还要简单一些。tomcat8.5以后使用netty写的。8.0之前用的是BIO。

相关文章
|
1月前
|
开发者
Netty运行原理问题之Netty高性能实现的问题如何解决
Netty运行原理问题之Netty高性能实现的问题如何解决
|
3月前
|
网络协议 Java 物联网
Netty是什么?深入理解高性能网络框架
Netty是什么?深入理解高性能网络框架
287 1
|
2月前
|
前端开发 Java 数据处理
使用Netty构建高性能的网络应用
使用Netty构建高性能的网络应用
|
4月前
|
编解码 网络协议 Java
netty有什么优势
Netty 是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。它的主要特点包括:开发门槛低, 定制能力强 ,高性能,活跃的社区.
|
4月前
|
XML 网络协议 前端开发
Netty网络框架(三)
Netty网络框架
56 1
|
4月前
|
存储 设计模式 网络协议
Netty网络框架(一)
Netty网络框架
415 1
|
4月前
|
存储 编解码 网络协议
Netty网络框架(二)
Netty网络框架
80 0
|
4月前
|
前端开发 网络协议 Dubbo
Netty - 回顾Netty高性能原理和框架架构解析
Netty - 回顾Netty高性能原理和框架架构解析
280 0
|
监控 NoSQL Java
Netty高性能架构之Reactor模式
在讨论Netty的架构模式之前,我们先来介绍下Reactor模式,因为Netty的架构模式是在此基础上演变而来的
Netty高性能架构之Reactor模式
|
监控 网络协议 NoSQL
Netty 高性能架构设计
Netty 高性能架构设计
183 0