反應堆模式(一):阻塞式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 )


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章