在提到高性能伺服器編程的時候肯定有聽過reactor模式,如果只是簡單的寫一個伺服器和客戶端建立連接的程式來熟悉一下使用socket函數編程,一般這種情況都是同步方式實現的,伺服器阻塞等待客戶端的連接,期間伺服器不能做其他事情。是不是有更好的實現方式,讓伺服器可以提高效率,這就是反應堆模式要做的。 ...
在提到高性能伺服器編程的時候肯定有聽過reactor模式,如果只是簡單的寫一個伺服器和客戶端建立連接的程式來熟悉一下使用socket函數編程,一般這種情況都是同步方式實現的,伺服器阻塞等待客戶端的連接,期間伺服器不能做其他事情。是不是有更好的實現方式,讓伺服器可以提高效率,這就是反應堆模式要做的。
- 同步方式
之前也說了,同步方式是在阻塞等待,會浪費大量的伺服器資源,效率不高,如果還不是多線程的話就更加的糟糕,當你在連接下載小視頻的時候,別人就下不了(連連接請求都會被伺服器忽視),別人就很氣。是很簡單的單線連接。
- 多線程方式
那麼為了處理多個客戶端的連接請求,為每個連接過來的客戶端單獨開出一個線程進行處理(這裡提到的多個線程中的每個線程都是同步方式實現的),每個線程中的每個操作都是阻塞的直到完成。就拿其優點來說,每個線程之間是比較獨立的,可以接受不同的請求執行不同的操作,並且由於是同步的方式,對於開發者來說開發也比較簡單(可以盡情地使用順序操作和阻塞操作)。
缺點也比較明顯:1.在多線程下使用同步方式是需要加鎖的!總要有點難度,要想使用共用資源就需要對這方面用點心;2.這麼多線程再切換的時候開銷是不能忽略不計的;3.移植性不高,因為有的機子不支持多線程。
下圖就是多線程實現的一個web伺服器的圖例
當伺服器開有多個線程,每個線程都相當於一個同步方式實現的web伺服器(就上面說的那種),這樣看似可以同時接收多個瀏覽器的請求,但是實則可供連接的數目是固定的,你開了多少個線程就能給多少個瀏覽器連接,如果需要增加同時連接的瀏覽器的數量,只能再多加幾個線程。同步的一些缺點也依然沒有解決。
- 反應器模式(reactor)
反應器模式聽起來名字高大上,簡單的來講就是select、poll、epoll的使用搭建出一個非同步方式的web伺服器,這裡的非同步通俗的講就是,當伺服器在等待瀏覽器連接請求的時候是自由的,不是阻塞的(同步是阻塞等待的),伺服器可以乾別的事情,當有瀏覽器的連接請求的時候,伺服器被通知,執行回調函數來建立起連接。下麵是一個反應堆模式實現的web伺服器的圖例,分別是連接請求和文件傳輸請求的web伺服器
HTTPHandle是事件處理器,主要負責事件來臨之後進行的操作,Initiation Dispatcher核心就是用select、poll、epoll實現的,當有請求到達Initiation Dispacher會通知http handler數據到來,應該去讀去解析了,基本是http handle主纜了大部分的工作
缺點就是可能對於http handle來說處理的事務略多會影響一部分性能並且過於冗雜(就是說太重了),讀寫操作內部本身還是同步的,在讀寫的過程中會浪費大量時間(畢竟讀寫比較慢),和之前的前攝器模式的那篇文章作對比來說,前攝器就是把讀寫操作讓給操作系統來做,減少時間浪費,把自身解放出來做其他事情,這就是前攝器和反應堆最大的差距。
參考資料:http://www.kuqin.com/ace-2002-12/Part-One/Chapter-8.htm