反应堆模式(一):阻塞式IO应用


 这里我假设一个简单的情景,比如一个运行在单cpu机器上的单线程ruby应用。实际上,操作系统把CPU时间切分为多个片段并做规律性的上下文切换。

在单线程应用例如运行在ruby on rails的应用,所有请求都通过一个单独的线程来处理。当这个单独的线程做IO相关处理如数据库查询或者网络调用,那么即使这个应用/线程可以处理其他请求相关的工作也还是会被这些IO操作所阻塞。

一个避免以上问题出现的方法就是为在同一个服务下运行多个应用程序。所以,当一个应用程序的线程被阻塞时,其他应用的线程可以继续使用CPU来处理其他请求。下图中有两个应用在竞争CPU的使用时间,其中第二个应用的CPU消耗时间在a1到a2之间,但是我们还是可以看到CPU在时间段a1到t1、a2到 t2之间还是空闲的。

为了使CPU没有任何空闲时间,我们可以再增加更多的应用,但是这会增加不必要的上下文切换进而导致性能进一步降低。如下图的例子中,第三个应用即使还在处理一个请求还需要更多CPU运行时间,但是还是会和第二个应用程序之间的线程进行切换。

如上图所示,我们注意到了两个问题:

1.CPU会从一个仍然需要CPU处理的应用中切换出来

2.CPU仍然会为一个等待IO操作的应用分配时间

这两个问题都是由于抢占式的线程切换。为了达到CPU的合理分配使用,应用需要以合作的方式来请求CPU时间或者放弃CPU时间,而不是通过抢占式来上线文切换。

C10K的问题

在2000年初,单个服务器一次不能处理超过10000个连接。这对应用来说是个限制,开发者不能在单个服务中做超过10000连接的应用。人们发现解决这个问题的方案就是在每个线程中使用非阻塞IO。非阻塞IO是在C10K问题清单中被作为一个可扩展问题来关注的。

反应堆模式针对以上问题提供了一个解决方案就是使用epoll模型。

http://en.wikipedia.org/wiki/Nonpreemptive_multitasking
http://en.wikipedia.org/wiki/Preemption_(computing)
http://en.wikipedia.org/wiki/Reactor_pattern

在第二部分我们将关注使用非阻塞IO作为解决CPU使用率最大化问题的一种方式。

(未完,待续...)

1.本文由程序员学架构翻译,由mathew同学校审;仅用于交流学习使用。

2.本文译自Venkatesh CM在Reactor Pattern Part 1 - Applications with Blocking I/O的博客。

3. 转载请务必注明本文出自:程序员学架构(微信号:archleaner )

4.关注公众号请扫码:

 

猜你喜欢

转载自yunjiechao-163-com.iteye.com/blog/2124578
今日推荐