本文仅作本人做笔记使用。
RPC发展之路
在了解Netty的高性能之前,我们不妨先看看传统的RPC是怎么做的
传统的RPC调用缺陷
对于传统的RPC而言,其调用性能是存在一定的瓶颈的。
一、网络传输方式问题
传统的RPC传输方式采用了同步阻塞I/O。一旦客户端的并发压力或者网络时延较大,就会导致I/O线程经常性的阻塞。 采用BIO通信模型的服务端的最大的问题,是其不具备弹性伸缩能力,当并发访问量大幅度增长后,线程数就会膨胀,系统的性能就会急剧下降。随着并发量的继续增加,可能会发生句柄溢出、线程堆栈溢出等问题。
二、序列化性能差
Java其自身的序列化也是有一些典型的缺陷。
Java的序列化机制是Java内部的对象编解码技术,无法跨语言使用。其次,相比于其他的开源的序列化框架,Java序列化后的码流过大,而且其序列化的性能较差,资源占用率高。
三、线程模型问题
由于其采用同步阻塞的BIO,每个TCP连接都占用1个线程。如果I/O读写阻塞,就会导致线程无法及时释放,导致系统性能急剧下降,严重的会导致虚拟机无法创建新的线程。
Netty的高性能
Netty作为一个高性能的NIO通信框架,已经被广泛适用于各种互联网消息中间件、游戏和金融行业中。
Netty其主要的优越点在于以下:
一、异步非阻塞通信
当我们遇到需要同时处理多个接入请求的时候,可以利用多线程或者I/O多路复用技术来处理。
I/O多路复用技术,是通过把多个I/O的阻塞复用到同一个select的阻塞上,从而使得系统在单线程的情况下依然可以同时处理多个请求。I/O多路复用的最大优势是系统开销小,系统无需创建新的进程或线程。
Netty的I/O线程NioEventLoop聚合了多路复用器Selector,可以同时并发处理多个SocketChannel。其读写操作都是非阻塞的,充分提升I/O线程的运行效率。
此外,Netty采用了异步通信模式,一个I/O线程可以并发处理N个客户端和读写操作,时期性能和弹性伸缩能力和可靠性都有很大的提升。
二、高效的Reactor线程模型
常见的Reactor线程模型有三种: (1)Reactor单线程模型 (2)Reactor多线程模型 (3)主从Reactor多线程模型
1、Reactor单线程模型
Reactor单线程模型,意思是所有的I/O操作都可以在一个NIO线程上面完成,可以处理包括接收客户端的TCP连接、向服务端发起的TCP连接、读取请求或应答消息、发送请求或应答消息等。
由于Reactor模式其所采用的异步非阻塞的I/O,理论上,一个线程就可以处理所有的I/O操作。
然而,在面对高负载、高并发的应用时,采用单线程模型则存在较大的不足。
因为一个线程如果要同时处理成百上千的链路,它即使是CPU负荷达到了100%,也难以满足其消息的编码解码读取发送等操作。
此外,一旦NIO线程的负载过重,其处理速度也会变慢,严重会导致大量客户端连接超时。超时了也往往会进行重发,这就更加使得NIO的线程负载更严重。
而且,也会存在一个可靠性的问题。只有一个NIO线程,如果不小心跑飞或者进入死循环,就会导致整个系统模块不可用。
基于以上问题,Netty升级出了Reactor多线程模型。