第4章 鼎鼎大名的Reactor模式
前言
而Reactor(反应器)模式是高性能网络编程在设计和架构层面的基础模式,算是基础的原理性知识。只有彻底了解反应器的原理,才能真正构建好高性能的网络应用、轻松地学习和掌握高并发通信服务器与框架(如Netty框架、Nginx服务器)。
正因为Reactor模式是高并发的重要基础原理,所以该模式也是BAT级别大公司必不可少的面试题。
Reactor模式的重要性
到目前为止,高性能网络编程都绕不开Reactor模式。很多著名的服务器软件或者中间件都是基于Reactor模式实现的。例如:
- “全宇宙有名的、高性能”的Web服务器Nginx就是基于Reactor模式的;
- 如雷贯耳的Redis,作为高性能的缓存服务器之一,也是基于Reactor模式的;
- 目前热门的在开源项目中应用极为广泛的高性能通信中间件Netty,还是基于Reactor模式的。
为什么首先学习Reactor模式
学习像Netty这样的“精品中的精品”框架也是需要先从设计模式入手的,而Netty的整体架构是基于Reactor模式的。
Reactor模式简介
Reactor模式的定义:
(1)Reactor线程的职责:负责响应IO事件,并且分发到Handlers处理器。
(2)Handlers处理器的职责:非阻塞的执行业务处理逻辑。
多线程OIO的致命缺陷
在Java的OIO编程中,原始的网络服务器程序一般使用一个while循环不断地监听端口是否有新的连接。如果有,就调用一个处理函数来完成传输处理。
这种方法的最大问题是:如果前一个网络连接的handle(socket)没有处理完,那么后面的新连接无法被服务端接收,于是后面的请求就会被阻塞,导致服务器的吞吐量太低。这对于服务器来说是一个严重的问题。
为了解决这个严重的连接阻塞问题,出现了一个极为经典的模式:Connection Per Thread(一个线程处理一个连接)模式。
Connection Per Thread模式的缺点是对应于大量的连接,需要耗费大量的线程资源,对线程资源要求太高。
如何解决Connection Per Thread模式的巨大缺陷呢?一个有效途径是使用Reactor模式。用Reactor模式对线程的数量进行控制,做到一个线程处理大量的连接。那么它是如何做到的呢?首先来看一个简单的版本——单线程的Reactor模式。