Netty 如何实现高性能

77 阅读4分钟
从 传统 BIO 多线程模型分析。

在传统的BIO模型中,客户端请求服务端,服务端承载所有的客户端请求。客户端请求进来之后,服务端将请求分发给不同的线程处理(通过new 线程,或者使用线程池的方式实现)。每个线程都要实现复杂的IO处理(读取数据、解码请求数据、执行逻辑运算请求数据、编码响应结果、返回等等)。一个处理的线程要经历这么长处理的流程。在BIO模型中,我们发起读取数据,系统是要调用内核,进行数据准备的,在IO操作的期间。cpu都是要等待被阻塞掉的线程。一个线程中的同步操作,让cpu在哪干等。明显系统的很多资源是被浪费的。

引入事件处理机制,在server 端添加一个线程专门处理IO操作

对引入的新线程来说,这个线程专门维护IO的连接,当网络请求有进来的数据的时候,将这次请求当作一个事件,分发给多个事件对应的channel进行处理。处理效率就会有所提升。处理速度赶不上的时候,线程也可以添加。易于扩展。

基于事件处理机制实现的 reactor 模型

reactor 模型 实现了事件机制与IO多路复用。事件机制负责把所有的IO事件分发给具体处理的这些线程。线程具体就不需要做这些IO等待的操作了(收到数据和发送对端数据)。事件分发器本事在reactor的实现里也是一个线程。他用来做IO连接的维护,内核是否将数据准备好这些操作由分发器线程完成。分发出去的事件则做业务相关的操作。此时真正的将IO相关的处理和业务相关的处理给隔离开了。从而实现业务处理线程都不被IO直接阻塞。此模式大大提高了网络对IO处理的性能。

reactor 单线程模型

image.png

reator 线程负责所有的工作,既负责作为selector轮询内核检查是否将数据准备好了,也负责维护网络连接socket相关的状态,并且轮询检查数据是否准备好。同时当数据准备好的时候,就可以从channel 中拿到数据了。之后调用对数据进行业务处理的handler。通过handler 执行业务操作相关的方法。单线程模型中,做业务处理的线程和做IO的线程和还是同一个线程。两个操作相互干扰,IO阻塞问题可想而知。

reactor 多线程(业务处理多线程,reactor单线程)模型

image.png

具体的业务由线程池来完成。由线程池去负责不同的准备好的IO的channel。读取每个channel里面的数据。对这些数据进行解码、计算、编码的操作。此操作真正将IO操作与业务操作分离开来。效率相比于之前有了更好的提升。但是 reactor线程不仅做了维护socket连接(获取事件【数据是否准备好】),和网络分发事件。都是由reactor线程做的。

image.png

拆分 reactor 线程,细粒度拆分reactor线程功能。Reactor 主从模型
  • mainReactor : 负责socket连接的维护,感知是否由数据可读。
  • subReactor : 做事件分发处理。
  • 线程池 : 处理业务逻辑。

image.png

此模型做到了,IO事件处理,事件分发,worker线程处理业务逻辑完全分离的效果,大大提升了效能。相互之间互不影响。 根据特点进行一些额外的处理。类比 GC 回收,根据对象特点产生不同分区/分代。根据特定进行垃圾回收处理。以此优化处理。

Netty 支持的模型
server端 单线程的reactor模型。
   EventLoopGroup enventGroup = new EventLoopGroup(1);
   ServerBootstrap serverBootstrap = new ServerBootstrap();
   serverBootstrap.set(enventGroup);
非主从 多线程模式
   EventLoopGroup enventGroup = new EventLoopGroup();
   ServerBootstrap serverBootstrap = new ServerBootstrap();
   serverBootstrap.set(enventGroup);
主从多线程模式
   EventLoopGroup boss = new EventLoopGroup();
   EventLoopGroup worker = new EventLoopGroup();
   ServerBootstrap serverBootstrap = new ServerBootstrap();
   serverBootstrap.set(boss,woker);

为什么叫 event loop ?内部是一个对Io来的事件进行处理的循环,看对应的 channel 里面没有数据。有数据就处理。把事件放在处理队列里,有事件就执行。是一个loop操作。 所以叫 event loop

image.png