004——Netty之高性能IO(Reactor)

一、原始方式

方法一:

# 使用while循环,不断监听端口是否有新的套接字链接 
while(true){    
socket = accept();  
handle(socket)  
} 
# 做法局限:处理效率低下,并发是请求只能阻塞

方法二:

# 一个连接对应一个线程
while(true){ 
socket = accept(); 
new thread(socket); 
} 
# 每个线程阻塞不会影响到后续请求,但对资源要求非常高。线程粒度大,每个线程一次性处理所有交互事情(连接、读取和写入),限制了吞吐量。

方法三:

# 将线程粒度减小。将一次连接的操作划分为更细的粒度或者过程。这样虽然线程数量变多,但是处理的事情更为简单和单一

二、Reactor定义

关键点
  • 事件驱动(event handling)

  • 可以处理一个或多个输入源(one or more inputs)

  • 通过Service Handler同步的将输入事件(Event)采用多路复用分发给对应Handler处理

处理流程
  • 同步的等待多个事件源到达(采用select()实现)
  • 将事件多路分解以及分配相应的事件服务进行处理,这个分派采用server集中处理(dispatch)
  • 分解的事件以及对应的事件服务应用从分派服务中分离出去(handler)
使用Reactor的原因

NIO的优点

  • 基于事件驱动(selector支持对多个Channel进行监听)
  • 统一事件处理分派中心(dispatch)
  • 事件处理服务

不足

  • 更少的开销,更少的上下文切换以及locking
  • 能够跟踪服务器状态
  • 能够管理handler 对event的绑定

三、Reactor模式

介绍

Reactor将被拆分的子过程对应到Handler上,每一种handler会处理一种event。Selector全局管理进行全局管理。我们只需要注册感兴趣的channel事件,selector就会通过轮询的方式不断检测channel上的事件是否发生。如果没有事件发生则线程阻塞,如果时间发生,则调用相应handler进行处理。

非Reactor模型

image

  • 这种模型由于IO在阻塞时会一直等待,因此在用户负载增加时,性能下降的非常快
  • serversocket的accept方法,阻塞等待client连接,直到client连接成功
  • 线程从socket inputstream读入数据,会进入阻塞状态,直到全部数据读完
  • 线程向socket outputstream写入数据,会阻塞直到全部数据写完

Reactor模型

  • Reactor 将I/O事件分派给对应的Handler
  • Acceptor 处理客户端新连接,并分派请求到处理器链中
  • Handlers 执行非阻塞读/写任务,Event绑定

单Reactor单线程模型
改进点:基于事件模式,当事件触发时,才调用处理器进行处理
image

  • 当新连接到来触发connect事件之后,交由Acceptor进行处理,并构造Handler
  • 有IO读写事件之后交给Hanlder处理。
  • 在获取到Client相关的SocketChannel之后,绑定到相应Handler上。
  • 若是连接事件获取是acceptor,若是IO读写事件获取是handler。都由Reactor进行分发

Acceptor主要任务就是构建handler ,在获取到和client相关的SocketChannel之后 ,绑定到相应的hanlder上,对应的SocketChannel有读写事件之后,基于racotor 分发,hanlder就可以处理了(所有的IO事件都绑定到selector上,有Reactor分发)。

单Reactor多线程模型
改进:使用多线程处理业务逻辑。
image

  • 专门一个IO线程——Acceptor线程负责监听服务端请求。
  • 消息读取、解码、编码、发送由线程池负责
  • 一个链路只对应一个线程,可以避免同步操作。
  • Reacpter只负责消息分发

多Reactor多线程模型

image

  • mainReactor负责监听 ServerSocketChannel ,用来处理客户端新连接的建立,并将建立的客户端的SocketChannel指定注册给 subReactor 。
  • subReactor 维护自己的 Selector ,基于 mainReactor 建立的客户端的 SocketChannel 多路分离 IO 读写事件,读写网络数据。对于业务处理的功能,另外扔给 worker 线程池来完成。
  • 该模式为Netty默认模式

https://blog.csdn.net/qq_24313635/article/details/80989450

猜你喜欢

转载自www.cnblogs.com/boycelee/p/10014417.html