一. 什么是reactor模式
讲这个之前,先整体上看看,一般的服务端架构设计都是怎么做的。
(1) 经典的Thread-based Architecture(线程模式)。
线程模式也有多种做法:
① accept read send等I/O操作,以及数据解析,业务处理等具体逻辑都在一个线程中完成。属于最基本的网络服务流程,要求是客户端连接是一次性的,不涉及来回交互(UDP通信),并且读写的数据量很少,业务逻辑很简单,处理速度很快。如此才能保证多客户端的及时响应,通常用于UDP循环服务器模型。(循环服务器模型指的是:服务器在处理一个客户端时不接受其他客户端的连接。并发服务器模型指的是: 服务器可以处理客户端并发访问。本篇笔记主要讨论并发服务器模型)
② accept 放在主线程中,一旦有客户端连接,则将连接下放到任务队列,后面跟一个线程池,不断从队列中取走连接任务,在子线程中执行read->parse->process->send流程。
优点: 简单直观,适合并发量不是很大的场景。
缺点:链接和线程始终保持一一对应的关系。如果客户端很多,并且都是长连接的话,会使大量线程一直是keep-Alive状态,并在空闲状态下等待,浪费大量的内存和堆栈空间;此外一个进程能够开启的线程数量是有限的,意味着任务队列也不能太大(太大了没有意义,即使放入了队列,也没办法被被及时处理),虽然通过多进程可以缓解(每个进程都有一个accpet,和一个线程池),但是治标不治本。
(2) Event-driven architecture (事件驱动模式)
将I/O的各种状态的变化封装成为事件,并使用I/O复用技术,实现单个线程处理多个客户端的I/O事件。(复用,我的理解就是多条连接共享同一个线程)。需要注意的是,parse->process这两步是具体的业务逻辑处理,不会被放在这个线程内部,可以通过额外的线程池处理。
reactor是事件驱动模式的一种具体参考指导(类似于指导规范),它在很多网络通信库中都有各自具体的实现,如ACE, libevent,ZeroMQ以及java中的netty等。另外,redis服务端也实现了reactor模式。
二. reactor模式解决的问题
根据上面的总结可知,reactor模式(或者说事件驱动模式)主要解决的就是多客户端高并发访问时,网络服务端可能由于资源耗尽而崩溃的问题。
三. reactor 的实现方法
待续...



