我记得《unix网络编程》,一共提到五种io模型:
阻塞IO模型 非阻塞IO模型 IO复用模型 信号驱动IO 异步IO模型
可是为什么我见过的web服务器,要么是用阻塞io+线程(比如apache),要么是多路复用(比如epoll),但在我看来后两种io才是最完美的解决方式,可是为什么web服务器没有使用呢?
是因为发送信号,这个操作太浪费了?所以对于web服务器这种要接受大量请求的,每一个io都发送信号代价太大?还是因为别的?
业精于勤,荒于嬉;行成于思,毁于随。
epoll 是 linux 2.6 以後才出現的,所以,Nginx 使用了 epoll 模型。所以,Nginx 處理靜態檔案或做反代很強行,因為主要是 IO 操作。
epoll 是 select/poll 的增強版,就是基於事件通知的。
Apache、Tomcat,他們雖然也是Web 伺服器,但也承擔應用伺服器的角色,之所以稱他們為應用程式伺服器,是因為他們真的要跑具體的商業應用,如科學計算、圖形圖像、資料庫讀寫等。它們很可能是 CPU 密集型的服務,事件驅動並不合適。
魚與熊掌不可兼得。事件驅動適合 IO 密集型服務,多進程或執行緒適合 CPU 密集型服務。
再者,根據 TCP、HTTP 協定的特點,大部分伺服器都會保留 time_wait 的持久連結。 Web 伺服器主要是用來處理 HTTP 協定的請求。
沒有最完美的,只有更適合的
node是異步io吧 而且確實性能很好
Nginx就是一個非同步IO的實作啊, 他有一個大的eventloop所以不允許有任何阻塞的進程不然會阻塞所有, 在開發一個nginx模組的時候尤其要注意這一點, 這也帶來了一些問題例如全非同步的IO會導致程式不宜讀,所以後期維護上可能會帶來問題這個時候Lua來了~~
我來說為什麼不使用同步非阻塞模型。
由於socket是非阻塞的方式,因此用戶執行緒發起IO請求時立即回傳。但並沒有讀取到任何數據,用戶執行緒需要不斷地發起IO請求,知道數據到達後,才真正讀取到數據,繼續執行。
使用者執行緒使用同步非阻塞IO模型的偽代碼描述為:
{ while(read(socketfd, buffer) != SUCCESS) ... process(buffer); }
也就是使用者需要不斷地呼叫read,嘗試讀取socket中的數據,直到讀取成功後,才繼續處理接收的資料。整個IO請求過程中,雖然用戶執行緒每次發起IO請求後可以立即返回,但是為了等到數據,仍需要不斷輪詢、重複請求,消耗了大量的CPU的資源。所以一般很少用這種模型。
為什麼不使用非同步IO模型? 1)非同步要透過大量的callback,hook函數實現,調試,維護,可讀性都是一個很大的挑戰,現在還沒有很好的工具集來支援非同步程式設計。 2)阻塞io+線程和多路復用已經比較好的解決了高並發問題,成本也不高。 3)非同步IO不一定真的非同步,例如POSIX AIO(glibc AIO),效能也不好。詳見異步IO應用
epoll 是 linux 2.6 以後才出現的,所以,Nginx 使用了 epoll 模型。所以,Nginx 處理靜態檔案或做反代很強行,因為主要是 IO 操作。
epoll 是 select/poll 的增強版,就是基於事件通知的。
Apache、Tomcat,他們雖然也是Web 伺服器,但也承擔應用伺服器的角色,之所以稱他們為應用程式伺服器,是因為他們真的要跑具體的商業應用,如科學計算、圖形圖像、資料庫讀寫等。它們很可能是 CPU 密集型的服務,事件驅動並不合適。
魚與熊掌不可兼得。事件驅動適合 IO 密集型服務,多進程或執行緒適合 CPU 密集型服務。
再者,根據 TCP、HTTP 協定的特點,大部分伺服器都會保留 time_wait 的持久連結。 Web 伺服器主要是用來處理 HTTP 協定的請求。
沒有最完美的,只有更適合的
node是異步io吧
而且確實性能很好
Nginx就是一個非同步IO的實作啊, 他有一個大的eventloop所以不允許有任何阻塞的進程不然會阻塞所有, 在開發一個nginx模組的時候尤其要注意這一點, 這也帶來了一些問題例如全非同步的IO會導致程式不宜讀,所以後期維護上可能會帶來問題這個時候Lua來了~~
我來說為什麼不使用同步非阻塞模型。
由於socket是非阻塞的方式,因此用戶執行緒發起IO請求時立即回傳。但並沒有讀取到任何數據,用戶執行緒需要不斷地發起IO請求,知道數據到達後,才真正讀取到數據,繼續執行。
使用者執行緒使用同步非阻塞IO模型的偽代碼描述為:
也就是使用者需要不斷地呼叫read,嘗試讀取socket中的數據,直到讀取成功後,才繼續處理接收的資料。整個IO請求過程中,雖然用戶執行緒每次發起IO請求後可以立即返回,但是為了等到數據,仍需要不斷輪詢、重複請求,消耗了大量的CPU的資源。所以一般很少用這種模型。
為什麼不使用非同步IO模型?
1)非同步要透過大量的callback,hook函數實現,調試,維護,可讀性都是一個很大的挑戰,現在還沒有很好的工具集來支援非同步程式設計。
2)阻塞io+線程和多路復用已經比較好的解決了高並發問題,成本也不高。
3)非同步IO不一定真的非同步,例如POSIX AIO(glibc AIO),效能也不好。詳見異步IO應用