塞爾吉奧是正確的。此時,您的應用程序可能更適合傳統的Apache/Passenger模型。如果你採取的是平坦的路線,尤其是在像Ruby這樣的單線程平臺上,那麼無論如何,你都不能阻塞任何東西,無論是數據庫,緩存服務器,還是其他的HTTP請求 - 什麼也不做。
這使得異步編程更加困難 - 通常以同步磁盤I/O或DNS解析的形式阻塞內容很容易。非阻塞(evented)框架(如nodejs)非常小心,因爲它們幾乎不會爲您提供阻塞的框架函數調用,而是使用回調(包括數據庫查詢)處理所有內容。
,如果你看一個單線程非阻塞服務器的心臟,這可能是更容易顯現:
while(wait_on_sockets(/* list<socket> */ &$sockets, /* event */ &$what, $timeout)) {
foreach($socketsThatHaveActivity as $fd in $sockets) {
if($what == READ) { // There is data availabe to read from this socket
$data = readFromSocket($fd);
processDataQuicklyWithoutBlocking($data);
}
elseif ($what == WRITE && $data = dataToWrite($fd)) { // This socket is ready to be written to (if we have any data)
writeToSocket($fd, $data);
}
}
}
您在上面看到什麼叫做事件循環。 wait_on_sockets
通常由操作系統以系統調用的形式提供,如select,poll,epoll或kqueue。如果processDataQuicklyWithoutBlocking時間過長,OS所維護的應用程序的網絡緩衝區(新請求,傳入數據等)最終會被填滿,並會導致它拒絕新的連接並超時現有的連接,因爲$ socketsThatHaveActivity處理速度不夠快。這與線程服務器(例如,典型的Apache安裝)不同,因爲每個連接都使用單獨的線程/進程提供服務,因此一旦傳入的數據到達應用程序就會讀入應用程序,並且傳出的數據將毫無延遲地發送。
當您創建(例如)數據庫查詢時,像nodejs這樣的非阻塞框架是將DB服務器的套接字連接添加到被監視的套接字列表($ sockets),因此即使您的查詢需要一會兒,你的(唯一的)線程不會被阻塞在那個套接字上。相反,他們提供了一個回調:
$db.query("...sql...", function($result) { ..handle result ..});
正如你可以在上面看到,db.query與數據庫服務器上的任何絕對沒有阻塞立即返回。這也意味着你經常要這樣寫代碼,除非編程語言本身支持異步功能(如新的C#):
$db.query("...sql...", function($result) { $httpResponse.write($result); $connection.close(); });
的永不不斷塊規則可以是如果你有很多程序有所放鬆每個都運行一個事件循環(通常是運行節點集羣的方式),或者使用線程池來維護事件循環(Java的jetty,netty等,你可以用C/C++編寫自己的代碼)。當一個線程被阻塞時,其他線程仍然可以執行事件循環。但是在負載足夠大的情況下,即使這些也無法執行。所以永遠不要在一臺服務器上堵塞。
正如你所看到的,服務器通常試圖解決一個不同的問題 - 它們可以有很多開放連接。他們擅長的地方就是隻需輕量計算(例如彗星服務器,像memcached,varnish,nginx,squid等代理的緩存)。即使它們擴展性更好,響應時間通常會增加(沒有什麼比爲連接預留整個線程更好),這是毫無價值的。當然,運行與併發連接數相同數量的線程在經濟/計算上可能並不合算。
現在回到你的問題 - 我會建議你保持Nginx的狀態,因爲它在連接管理(基於事件)方面非常出色 - 通常意味着處理HTTP保持活動,SSL等。然後你應該連接這個到使用FastCGI的Rails應用程序,您仍然需要運行工作人員,但不必重寫您的應用程序以完全放完。您還應該讓Nginx提供靜態內容 - 讓您的Rails工作者與Nginx通常可以做得更好的事情聯繫在一起毫無意義。這種方法通常比Apache/Passenger的規模要好得多,特別是如果你運行的是高流量的網站。
如果你可以編寫你的整個應用程序,那就太好了,但我不知道Ruby是多麼容易或困難。
哇..感謝Tejas的詳細迴應。所以我從網上讀取的基準測試...是否適用於完全不同的應用程序類型? Thin自己的網站提供了一個Rails應用程序作爲瘦客戶端示例應用程序。 http://code.macournoyer.com/thin/。我的印象是,我可以用瘦身來代替乘客,一切都會變得h h。 –
只要你不阻止任何地方,你應該能夠重新創建這些基準。 – tejas