Skip to content

Instantly share code, notes, and snippets.

@yangyi
Created March 25, 2016 17:01
Show Gist options
  • Save yangyi/3b28f4f445765ac624e1 to your computer and use it in GitHub Desktop.
Save yangyi/3b28f4f445765ac624e1 to your computer and use it in GitHub Desktop.
Reactor Pattern

高性能的服务器,Reactor 是一种非常见的模式。Nginx, NodeJS, eventmachine, twisted 都使用了这种模式来实现高性能的服务器。

  • 为什么 Reactor 能够实现高性能服务器?
  • 怎么实现 Reactor?
  • Reactor 到底是同步还是异步?

为什么 Reactor 能实现高性能的服务器?

TLTR

Reactor 模式中,通过 event driven IO (select), 当新的 event 到达(比如数据 ready 了)的时候,就可以处理 IO 了。整个系统以 IO event 为中心,最大程度的利用了系统的 IO。

详细的解释

性能的瓶颈,可以分为两个,CPU 和 IO。

  1. IO 比 CPU 慢的多
  2. 在大多数的商业应用中,大多数是 IO 操作,而不是科学计算。

因为上面两个原因,优化 IO 的效率,比优化 CPU 的效率更加重要

使用 blocking IO API 的时候的情况

如果 IO 阻塞了(比如客户端网络比较慢), 处理这个 socket 的线程/进程就被阻塞了。多线程模型当中,可以使用多个 thread,这样当一个 thread 被阻塞了,可以读。但是操作系统调度这些进程,并不是根据 IO 是否。而根据的是 thread 优先级,或者这个 thread 的 CPU 占用时间,所以 IO 并没有最大程度的得到利用。

而 reactor 模式呢?

完全是以 IO 为中心,当一个新的 IO event(accept/read/write) 发生的时候,可以马上调用 Handler 去处理这个 event。这样最大化的利用了 IO。

怎么实现 Reactor?

在 linux 当中,可以使用 epoll, Java 当中,对应的就是 java.nio 里面的 Channels/Buffers/Selectors

基本的实现可以参考 http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf

Reactor 到底是同步还是异步?

  1. Reactor 里面,select 是同步的操作, 读写也是同步的操作,调用 select 和 read/write 的进程也是被 block 住了.
  2. 但是在使用的层面上,比如 NodeJS, 比如读一个文件,我是提供一个回调函数 request.on('data', => {...}),当有新的数据读到的时候,调用我提供的回调函数。因为一直只在使用层面上,所以我说是异步的。

参考文档

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment