【转】http://wiki.jerrypeng.me/io-multiplexing-reactor.html
IO多路复用和Reactor模式
1. Reactor和Preactor模式
- Reactor用于同步IO,Preactor用于异步IO
- Reactor通常会和Connector模式一起使用,进一步解耦连接的建立与连接以后的逻辑
2. Reactor模式中的主要角色
2.1. Reactor
Reactor是IO事件的派发者。
2.2. Acceptor
Acceptor接受client连接,建立对应client的Handler,并向Reactor注册此Handler。
2.3. Handler
和一个client通讯的实体,按这样的过程实现业务的处理。一般在基本的Handler基础上还会有更进一步的层次划分, 用来抽象诸如decode,process和encoder这些过程。比如对Web Server而言,decode通常是HTTP请求的解析, process的过程会进一步涉及到Listner和Servlet的调用。业务逻辑的处理在Reactor模式里被分散的IO事件所打破, 所以Handler需要有适当的机制在所需的信息还不全(读到一半)的时候保存上下文,并在下一次IO事件到来的 时候(另一半可读了)能继续中断的处理。为了简化设计,Handler通常被设计成状态机,按GoF的state pattern来 实现。
3. 多线程下的Reactor
一个突然闪入脑海的问题:在单核的机器上,如果除了Reactor可能阻塞在等待IO事件中以外,Handler和Acceptor都是完全 非阻塞的,那用多线程来实现Reactor模式能获得性能提升吗?(貌似不能……)
3.1. 多线程化的目的
- 利用上多核的计算能力。
- 策略性地增减线程从而提升伸缩性。
- 要让Reactor能快速派发IO事件到Handler中。如果用单线程,Handler处理快慢直接影响队列中后续IO事件的派发速度。
- IO之外的处理交给其他线程,这样Reactor可以专心派发事件。
- 可以采用多Reactor的设计,因为:
- 如果负载高的话,单个Reactor可能会忙于IO,影响伸缩性。
- 其实多Reactor就是一种负载均衡的策略,从而不会让CPU在IO十分频繁的时候空闲下来。
- 线程划分为Reactor线程和Worker线程,前者处理IO并派发事件,后者来跑Handler做完IO后的Process处理。
Doug Lea的《Scalable IO in Java》中实例代码中,多线程版本的Handler还是在Reactor线程里运行,只有在读到 需要的数据了以后才会想Worker线程池里提交process的任务。个人对于这种有一个问题:如果不能一次读到全部需要 的数据,process过程该如何设计? (TODO:争取从Jetty中找到一些答案)
3.1.1. Worker线程
- 分担非IO的业务逻辑处理,减轻Reactor负担
- 用线程池来管理,以便做性能和伸缩性之间的微调和控制
- 通常需要的线程远远低于同时连接的client数量
- 任务之间的协调(TODO:需要更进一步的了解)
- Handoff
- Callback
- Queue
- Future
4. Java中的实现
Java中Reactor模式server的实现主要应用的两大块技术就是:
- Java5引入的concurrent包(传送门)
- ThreadPoolExecutor实现线程池
- Queue, Future等等机制的使用
- Java NIO(传送门)
- Channel
- Buffer
- Selector
4.1. 多Reactor线程的实现
- 静态创建 vs 动态创建
- 每个Reactor都有独立的Selector和对应的线程
- Reactor划分为main reactor和sub reactor
- main reactor监听连接请求并控制acceptor(单个main reactor?)
- sub reactors监听连接并分发IO事件到handler里
- Acceptor用某种机制来将accept后创建的handler分发到Reactor中
- Round-robin?
- 负载均衡?
4.2. 应用NIO其他Feature
- 单Reactor多Selector的模式:将不同的handlers绑定到不同的IO事件上
- 需要控制好同步
- 文件传送:应用OS提供的sendfile调用来直接将文件数据发送到网络连接中,省去了用户空间和内核空间的一次数据拷贝
- Direct Buffers:可以实现零拷贝的数据传送,但有创建和销毁的开销,适合长连接应用
- 参见NIO相关话题(传送门)
相关推荐
Libevent 源码解析 Libevent 是一个高性能的事件驱动库,广泛应用于网络编程和高... Libevent 的架构设计、事件处理机制、Reactor 模式、事件循环、IO 多路复用等方面的知识点,对于理解和使用 Libevent 至关重要。
io多路复用 用来检测IO 非阻塞 io 只用来操作IO reactor 是异步事件吗? 是,它里面 针对io 的处理是 异步回调的方式。 reactor为什么搭非阻塞io? (由三方面讨论) 多线程环境 将一个listenfd放到多个epoll去处理 ...
本项目深入探讨了Java网络编程中的多种模式,包括BIO(阻塞IO)、NIO(非阻塞IO)、IO多路复用(select、poll、epoll)、Reactor模式,以及零拷贝技术。通过这些实现,项目展示了如何在高并发环境下优化网络通信效率...
reactor中的 IO 使用的是select poll epoll 多路复用IO, 以便提高 IO 事件的处理能力,提高IO事件处理效率,支持更高的并发 。 二、Reactor 模型有三个重要的组件: 多路复用器:由操作系统提供,在 linux 上一般是...
本文主要对比了两种主要的I/O多路复用模式:Reactor和Proactor,这两种模式都是为了克服传统阻塞I/O的性能瓶颈而提出的。 首先,阻塞I/O在调用操作时会占用调用线程,直到操作完成,导致资源浪费和低效率。而非阻塞...
客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有IO请求就进行处理。 AIO : Asynchronous IO,即异步非阻塞,采用了 Proactor 模式,特点是先由操作系统完成后才通知服务端程序启动线程去处理...
五种IO模型分别是阻塞IO模型、非阻塞IO模型、IO多路复用模型、信号驱动IO模型和异步IO模型。其中IO多路复用模型包括select、poll和epoll三种实现方式。 3. select、poll和epoll原理和对比 select是POSIX标准的API...
1.利用IO多路复用技术Epoll与线程池实现Reactor高并发模型。 2.利用主从状态机解析HTTP请求报文,实现对资源的请求。 3.使用升序双向链表实现定时器,关闭超时的非活动连接。 4.单例模式的日志系统,实现异步写入...
NIO(Non-blocking IO)是同步非阻塞IO,通过IO复用(如select、poll、epoll)实现多路复用,提高了系统资源利用率,适用于高并发场景。AIO(Asynchronous IO)或NIO.2引入了异步非阻塞IO,进一步简化了编程模型,...
(3)IO多路复用(IOMultiplexing):即经典的Reactor设计模式,有时也称为异步阻塞IO,Java中的Selector和Linux中的epoll都是这种模型。(4)异步IO(AsynchronousIO):即经典的Proactor设计模式,也称为异步非...
总结来说,Java NIO通过其非阻塞特性、多路复用能力以及高效的Reactor模型,能够处理成千上万级别的并发连接,大大提升了服务器的性能。这使得它非常适合构建高并发的网络应用,比如大型网站、即时通讯服务、游戏...
NIO的核心组件是Selector,它是一个监管多个Channel的多路复用器,能够检测一个或多个Channel是否处于就绪状态,即检查Channel是否有I/O操作可执行。这种模式使得仅需要一个或几个线程就能管理多个Channel,大大降低...
这两类都要使用到IO多路复用,O多路复用是指单个进程/线程就可以同时处理多个IO请求。有三个方式select、poll、epoll。 select:将文件描述符放入一个集合中,调用select时,将这个集合从用户空间拷贝到内核空间...
3. **多路复用与并发**:在EC20模块上可能使用了多路复用技术,如select、poll、epoll等,允许一个进程同时处理多个TCP连接,提高服务效率。 4. **并发数据传输**:在多路SOCKT环境中,如何有效地管理和同步各个...
事件驱动模型、单线程处理多任务、非阻塞 I/O,I/O 读写不再阻塞,而是返回0、基于 block 的传输比基于流的传输更高效、更高级的 IO 函数 zero-copy、IO 多路复用大大提高了 Java 网络应用的可伸缩性和实用性。...
史蒂文斯在《UNIX网络编程》中介绍了五种基本的I/O模型:阻塞I/O、非阻塞I/O、I/O多路复用(如select和poll)、信号驱动的I/O(SIGIO)以及异步I/O(POSIX的aio_functions)。阻塞I/O是最基础的模型,当调用I/O操作...
其核心特性是支持多种IO多路复用技术,如epoll、kqueue、select和poll,这些技术使得libevent能够高效地处理大量的并发连接,降低了系统的资源消耗。 libevent的核心设计理念是基于reactor模式。在 reactor模式中,...