Reactor模式详解

简介

Reactor是一种开发模式,模式的核心流程是:
注册感兴趣的事件 -> 扫描是否有感兴趣的事件发生 -> 事件发生后做出现就处理(handler)
image.png

反应器模式是由Reactor反应器线程、和Handler处理器两大角色组成。
1) 反应器线程负责接收响应IO事件,并且分发到Handler处理器
2) handler处理器: 非阻塞执行业务逻辑

网络服务socket监听处理的发展过程

单线程阻塞监听

while(true)轮询 一个socket连接后,监听线程一直阻塞到当前socket处理完毕后才能接收下一个socket

  1. ServerSocket ss = new ServerSocket(8080);
  2. while (!Thread.interrupted()){
  3. Socket socket = ss.accept();
  4. // 读数据
  5. InputStream inputStream = socket.getInputStream();
  6. // 处理数据
  7. byte[] output = process(inputStream);
  8. // 返回结果
  9. socket.getOutputStream().write(output);
  10. }

多线程 Connection Per Thread

image.png

一个线程一个连接,每个线程独自处理自己负责的输入输出。服务器的监听线程也是独立的。
为什么不能一个线程处理多个socket请求?
传统OIO输入输出是阻塞的,前一个socket被阻塞后一个也处理不了,所以只能一个线程一个连接。

优点:解决了新连接被严重阻塞的问题。
缺点:难以支持高并发的用户socket连接,因为线程的创建和销毁会消耗大量的系统性能。

单线程Reactor

image.png
简单地说就是Reactor反应器和Handlers处理器处于同一个线程中执行。
SelectionKey的attach和attachment 相当于set和get, attach是把附件粘在SelectionKey上,而attachment则是选择键被选中时,把附件取出。

多线程reactor反应器

第一次:把IO耗时操作 decode/compute/encode 放在线程池中来做
image.png

第二种:
mainReactor负责接收所有的请求,然后分发给subReator,一个subReactor一个线程
Handler方面,线程池处理高耗时io操作
image.png

首先升级Handler,既要使用多线程,又要提高效率,考虑使用线程池
其次是升级Reactor, 考虑使用多个Selector

实现:

  1. 把处理IO操作,交给线程池去处理。业务和负责监听 与 IO操作的反应线程 完全隔离。
  2. 多核心cpu服务器,可以拆分多个SubReactor,分配多个Selector. 一个SubReactor一个线程,负责一个选择器。充分释放系统资源,提高反应器管理大量连接 ,提升大量通道的能力。