vlambda博客
学习文章列表

一文剖析Reactor 模型

Reactor定义

     Reactor中文翻译:反应器,所以Reactor模型就是反应器模型。Reactor 模型是网络服务器端用来处理高并发网络 IO 请求的一种编程模型。

   该模型主要有三类处理事件:即连接事件、写事件、读事件;三个关键角色:即 reactor、acceptor、handler。

acceptor负责连接事件,handler负责读写事件,reactor负责事件监听和事件分发。

Reactor的3种线程模型

1.单 Reactor 单线程

编辑 切换为居中


Doug Lea的单线程模型


  由上图可以看出,单Reactor单线程模型中的 reactor、acceptor 和 handler 的功能都是由一个线程来执行的。reactor 负责监听客户端事件和事件分发,一旦有连接事件发生,它会分发给 acceptor,由 acceptor 负责建立连接,然后创建一个 handler。如果是读写事件,reactor 将事件分发给 handler 进行处理。handler 负责读取客户端请求,进行业务处理,并最终给客户端返回结果。

一文剖析Reactor 模型

编辑 切换为居中


单 reactor 单线程


2.单 reactor 多线程

一文剖析Reactor 模型

编辑 切换为居中


Doug Lea单 reactor 多线程


 该模型中,reactor、acceptor 和 handler 的功能由一个线程来执行,与此同时,会有一个线程池,由若干 worker 线程组成。在监听客户端事件、连接事件处理方面,这个类型和单 rector 单线程是相同的,但是不同之处在于,在单 reactor 多线程类型中,handler 只负责读取请求和写回结果,而具体的业务处理由 worker 线程来完成。

一文剖析Reactor 模型

编辑 切换为居中


单 reactor 多线程


3.主-从 Reactor 多线程

一文剖析Reactor 模型

编辑 切换为居中


Doug Lea主-从 Reactor 多线程


在这个类型中,会有一个主 reactor 线程、多个子 reactor 线程和多个 worker 线程组成的一个线程池。其中,主 reactor 负责监听客户端事件,并在同一个线程中让 acceptor 处理连接事件。一旦连接建立后,主 reactor 会把连接分发给子 reactor 线程,由子 reactor 负责这个连接上的后续事件处理。那么,子 reactor 会监听客户端连接上的后续事件,有读写事件发生时,它会让在同一个线程中的 handler 读取请求和返回结果,而和单 reactor 多线程类似,具体业务处理,它还是会让线程池中的 worker 线程处理。刚才介绍的 Netty 使用的就是这个类型。

编辑 切换为居中


主-从Reactor多线程


常见框架中Reactor模型的使用

1. Redis

 Redis是典型的单Reactor单线程类型。Redis 主要通过aeMain、aeProcessEvents,以及 aeCreateFileEvent三个关键函数来实现Reactor模型,对源码(Linux系统)的整理如下:

源码文件

函数

被调用点

主要功能

ae.c/ae.h

aeMain()

server.c的main()

事件捕获,分发和循环处理

ae.c/ae.h

aeProcessEvents()

ae.c的aeMain()

根据事件类型进行响应的处理

ae.c/ae.h

aeApiPoll()

ae.c的aeProcessEvents()

调用操作系统的IO多路方法

Linux内核文件

epoll_wait()

ae.c的aeApiPoll()

检测并返回内核中网络IO事件

有兴趣的可以下载redis的源码,下图为源码截图

编辑 切换为居中


redis reactor源码


2. nginx

nginx是多进程模型,master进程不处理网络IO,每个Wroker进程是一个独立的单Reacotr单线程模型。,详情参考官方文档:Inside NGINX: Designed for Performance & Scalability

3. Netty

Netty 的线程模型主要是基于Reactor 模型,但是可以灵活配置,单reactor 单线程,单reactor多线程,和多reactor 多线程模型。

4. kafka

 kafka采用的是主从Reactor多线程模型,因为Kafka主要与磁盘IO交互,因此真正的读写数据不是从Reactor处理的,而是有一个worker线程池,专门处理磁盘IO,从Reactor负责网络IO,然后把任务交给worker线程池处理。

参考

Doug Lea关于reactor的论文

Nginx Reactor模型


原文链接:【重磅推荐】一文剖析Reactor 模型