ruby-on-rails - rails - ruby server



Ruby on Rails服務器選項 (1)

為我的Ruby on Rails應用程序設置開發服務器的整個問題讓我感到困惑。 我相信有WEBrick,Mongrel,Passenger,Apache,Nginx等等,我不太了解他們扮演的角色。

我開始使用WEBrick,現在我使用Mongrel進行開發。 這些服務器是獨立的,還是坐在Apache前面?

我已閱讀了關於Passenger的內容,但我並不真正了解它是什麼,該網站稱“可以輕鬆部署Ruby Web應用程序”,它是否取代了Mongrel? 它是否像Capistrano,它也部署Web應用程序?

考慮到我想測試SSL,我相信這不被mongrel支持,什麼是最好的開發服務器設置?

謝謝


取決於上下文,“部署”這個詞可以有兩個含義。 您還將Apache / Nginx的角色與其他組件的角色相混淆。

歷史性註釋:本文最初編寫於2010年11月6日,當時Ruby應用服務器生態系統受到限制。 我已於2013年3月15日更新了這篇文章,其中包含生態系統中的所有最新更新。

免責聲明 :我是應用服務器之一Phusion Passenger的作者之一。

Apache與Nginx

他們都是網絡服務器。 他們可以提供靜態文件,但是 - 使用正確的模塊 - 還可以提供動態Web應用程序,例如用PHP編寫的應用程序。 Apache更受歡迎,功能更多,Nginx體積更小,速度更快,功能更少。

Apache和Nginx都不能直接為Ruby Web應用程序提供服務,因此您需要將Apache / Nginx與某種附加組件結合使用(稍後介紹)。

Apache和Nginx也可以充當反向代理,這意味著它們可以接收一個傳入的HTTP請求並將其轉發到另一個服務器,該服務器也會說HTTP。 當該服務器響應HTTP響應時,Apache / Nginx會將響應轉發回客戶端; 稍後您將了解為什麼這是相關的。

Mongrel和其他生產應用程序服務器與WEBrick

Mongrel是一個Ruby“應用程序服務器”:具體而言,這意味著Mongrel是一個應用程序,它:

  1. 將您的Ruby應用程序加載到其自己的進程空間中。
  2. 設置一個TCP套接字,允許它與外部世界(例如互聯網)進行通信。 Mongrel在此套接字上偵聽HTTP請求,並將請求數據傳遞給Ruby Web應用程序。
  3. Ruby web應用程序然後返回一個對象,該對象描述了HTTP響應應該是什麼樣子,而Mongrel負責將其轉換為實際的HTTP響應(實際字節)並通過套接字將其發回。

然而Mongrel相當過時,現在它不再被維護。 較新的替代應用程序服務器是:

  • Phusion乘客
  • 獨角獸
  • 美洲獅
  • 特立尼達(僅限JRuby)
  • TorqueBox(僅JRuby)

我會在後面介紹他們,並描述他們與其他人以及來自Mongrel的不同之處。

WEBrick和Mongrel一樣,但不同之處在於:

  • WEBrick不適合生產,與我之前提到的其他一切不同。 WEBrick完全是用Ruby編寫的。 Mongrel(和大多數其他Ruby應用程序服務器)是Ruby的一部分,也是C的一部分(主要是Ruby),但是它的HTTP解析器是用C語言編寫的,因為它的性能很好。
  • WEBrick速度較慢且不太健壯。 它有一些已知的內存洩漏和一些已知的HTTP解析問題。
  • 默認情況下,WEBrick通常僅在開發過程中用作默認服務器,因為WEBrick包含在Ruby中。 Mongrel和其他應用程序服務器需要單獨安裝。 不建議在生產環境中使用WEBrick,但由於某些原因,Heroku選擇WEBrick作為其默認服務器。 他們之前使用Thin,所以我不知道他們為什麼切換到WEBrick。

應用服務器和世界

所有當前的Ruby應用程序服務器都會使用HTTP,但有些應用程序服務器可能會直接通過端口80向Internet公開,而其他應用程序則可能不會。

  • 可直接接觸互聯網的應用服務器:Phusion Passenger,Rainbows
  • 可能不直接暴露於互聯網的應用服務器:Mongrel,Unicorn,Thin,Puma。 這些應用服務器必須放在像Apache和Nginx這樣的反向代理Web服務器後面。
  • 我對特立尼達和TorqueBox不太了解,所以我省略了它們。

為什麼必須將一些應用程序服務器放在反向代理之後?

  • 一些應用程序服務器只能同時處理1個請求,每個進程。 如果你想同時處理2個請求,你需要運行多個應用服務器實例,每個實例服務於同一個Ruby應用。 這組應用程序服務器進程稱為應用程序服務器群集 (因此名稱為Mongrel群集,瘦群集等)。 然後,您必須設置Apache或Nginx以將代理轉換為此群集。 Apache / Nginx將負責在集群中的實例之間分配請求(關於這一部分的“I / O並發模型”部分)。
  • Web服務器可以緩存請求和響應,保護應用程序服務器免受“慢速客戶端”的影響 - 不會很快發送或接受數據的HTTP客戶端。 您不希望您的應用程序服務器在等待客戶端發送完整請求或接收完整響應時不執行任何操作,因為在此期間,應用程序服務器可能無法執行其他任何操作。 Apache和Nginx在同時做很多事情方面非常擅長,因為它們是多線程的或者是偶數的。
  • 大多數應用程序服務器可以提供靜態文件,但不是特別擅長。 Apache和Nginx可以更快地完成任務。
  • 人們通常將Apache / Nginx設置為直接提供靜態文件,但將不與靜態文件相對應的請求轉發到應用服務器,這是很好的安全措施。 Apache和Nginx非常成熟,可以屏蔽應用程序服務器(可能是惡意)損壞的請求。

為什麼一些應用程序服務器可以直接暴露於互聯網?

  • Phusion Passenger與所有其他應用服務器是完全不同的野獸。 其獨特功能之一是它集成到Web服務器中。
  • Rainbows作者公開表示將其直接暴露給互聯網是安全的。 作者相當肯定HTTP解析器(和類似的)沒有漏洞。 儘管如此,作者並沒有提供保證,並表示使用是有風險的。

比較應用服務器

在本節中,我將比較我提到的大多數應用程序服務器,但不是Phusion Passenger。 Phusion Passenger與其他動物是截然不同的,我給了它一個專門的章節。 我也省略了Trinidad和TorqueBox,因為我不太了解它們,但是如果您使用JRuby,它們只是相關的。

  • 雜種是非常光禿禿的骨頭。 如前所述,Mongrel純粹是單線程的多進程,所以它只在群集中有用。 沒有進程監控:如果群集中的進程崩潰(例如,由於應用程序中的錯誤),則需要手動重新啟動。 人們傾向於使用外部流程監控工具,如Monit和上帝。
  • 獨角獸是Mongrel的分支。 它支持有限的進程監視:如果進程崩潰,它將自動由主進程重新啟動。 它可以使所有進程在單個共享套接字上監聽,而不是為每個進程單獨分配一個套接字。 這簡化了反向代理配置。 像Mongrel一樣,它純粹是單線程的多進程。
  • Thin通過使用EventMachine庫來使用均衡的I / O模型。 除了使用Mongrel HTTP解析器外,它不以任何方式基於Mongrel。 它的集群模式沒有進程監視,所以你需要監視崩潰等。沒有獨角獸的共享套接字,所以每個進程在它自己的套接字上偵聽。 從理論上講,Thin的I / O模型允許高並發性,但在Thin用於大多數實際情況下,一個Thin進程只能處理1個並發請求,因此您仍然需要集群。 更多關於“I / O並發模型”一節中的這個特殊屬性。
  • Puma也是從Mongrel中分出來的,但與Unicorn不同,Puma被設計為純粹的多線程。 因此目前沒有內置的集群支持。 您需要特別注意確保您可以使用多個內核(更多關於此內容的“I / O並發模型”部分)。
  • Rainbows通過使用不同的庫支持多種並發模型。

Phusion乘客

Phusion Passenger的工作方式與其他所有工作方式大不相同。 Phusion Passenger直接集成到Apache或Nginx中,因此可以與Apache的mod_php進行比較。 就像mod_php允許Apache為PHP應用程序提供服務一樣,幾乎神奇地,Phusion Passenger允許Apache(也包括Nginx!)幾乎神奇地為Ruby應用程序提供服務。 Phusion Passenger的目標是讓盡可能少麻煩的一切正常工作(tm)。

使用Phusion Passenger,您無需為您的應用程序啟動進程或群集,並將Apache / Nginx配置為向靜態文件提供靜態文件和/或反向代理請求,而只需:

  1. 您可以編輯Web服務器配置文件並指定您的Ruby應用程序的“公共”目錄的位置。
  2. 沒有第二步。

所有配置都在Web服務器配置文件中完成。 Phusion Passenger幾乎可以自動完成所有的事情。 無需啟動集群並管理進程。 啟動/停止進程,在崩潰時重啟進程等 - 全部自動化。 與其他應用程序服務器相比,Phusion Passenger的移動部件少得多。 這種易用性是人們使用Phusion Passenger的主要原因之一。

與其他應用程序服務器不同,Phusion Passenger主要使用C ++編寫,因此速度非常快。

另外還有一個Phusion Passenger的Enterprise版本 ,它具有更多的功能,例如自動滾動重啟,多線程支持,部署錯誤抵抗等。

由於上述原因,Phusion Passenger是目前最流行的Ruby應用程序服務器,為超過150,000個網站提供支持,其中包括紐約時報,皮克斯,Airbnb等大型網站。

Phusion Passenger vs其他應用服務器

Phusion Passenger提供了更多的功能,並提供了許多優於其他應用程序服務器的優勢,例如:

  • 根據流量動態調整流程數量。 我們在我們的資源受限的服務器上運行了大量不屬於公共的Rails應用程序,並且我們組織中的人員一天最多只能使用幾次。 比如Gitlab,Redmine等。Phusion Passenger可以在不使用這些進程的時候降低這些進程的速度,並在他們使用時將其旋轉起來,從而為更重要的應用程序提供更多資源。 使用其他應用程序服務器時,您的所有進程始終處於打開狀態。
  • 某些應用服務器在設計上並不擅長某些工作負載。 例如Unicorn專為快速運行的請求而設計:請參閱Unicorn網站部分“在某些情況下更糟糕”。

Unicorn不擅長的工作量是:

  • 流式工作負載(例如Rails 4直播或Rails 4模板流式傳輸)。
  • 應用程序執行HTTP API調用的工作負載。

Phusion Passenger Enterprise 4或更高版本中的混合I / O模型使其成為這類工作負載的理想選擇。

  • 其他應用程序服務器要求用戶每個應用程序至少運行一個實例。 相比之下,Phusion Passenger在單一實例中支持多個應用程序。 這大大減少了管理開銷。
  • 自動用戶切換,方便的安全功能。
  • Phusion Passenger支持許多MRI Ruby,JRuby和Rubinius。 Mongrel,Unicorn和Thin僅支持MRI。 彪馬也支持所有3。
  • Phusion Passenger實際上支持的不僅僅是Ruby! 它還支持Python WSGI,因此它也可以運行Django和Flask應用程序。 事實上,Phusion Passenger正在朝著成為多語種服務器的方向發展。 待辦事項列表上的Node.js支持。
  • 帶外垃圾收集。 Phusion Passenger可以在正常的請求/響應週期之外運行Ruby垃圾收集器,這可能會將請求時間縮短數百毫秒。 獨角獸也有類似的功能,但Phusion Passenger的版本更加靈活,因為1)它不限於GC,可用於任意工作。 2)Phusion Passenger的版本適用於多線程應用程序,而Unicorn則不適用。
  • 自動滾動重啟。 Unicorn和其他服務器上的滾動重啟需要一些腳本工作。 Phusion乘客企業為您完全自動化這種方式。

有更多的功能和優勢,但名單真的很長。 您應參閱全面的Phusion乘客手冊( Apache版本Nginx版本 )或Phusion乘客網站以獲取信息。

I / O並發模型

  • 單線程多進程。 傳統上,這是Ruby應用服務器最流行的I / O模型,部分原因是Ruby生態系統中的多線程支持非常糟糕。 每個進程一次只能處理1個請求。 Web服務器在進程之間負載平衡。 這個模型非常強大,程序員很少有機會引入並發錯誤。 但是,它的I / O並發性非常有限(受進程數量的限制)。 該模型非常適用於快速,短期運行的工作負載。 它非常不適合緩慢,長時間運行的阻塞I / O工作負載,例如涉及調用HTTP API的工作負載。
  • 純粹的多線程。 現在,Ruby生態系統擁有出色的多線程支持,因此這種I / O模型已經變得非常可行。 多線程允許高I / O並發性,使其適用於短期運行和長時間運行的阻塞I / O工作負載。 程序員更可能引入並發錯誤,但幸運的是,大多數Web框架的設計方式仍然不太可能。 但需要注意的是,由於使用了全局解釋器鎖(GIL),MRI Ruby解釋器即使在有多個線程時也不能利用多個CPU內核。 您可以通過使用多個多線程進程來解決此問題,因為每個進程都可以利用一個CPU內核。 JRuby和Rubinius沒有GIL,所以他們可以在一個進程中充分利用多個內核。
  • 混合多線程多進程。 主要由Phusion Passenger Enterprise 4及更高版本實施。 您可以輕鬆地在單線程多進程,純多線程或甚至多個進程之間切換,每個進程都有多個線程。 這個模型給了兩全其美。
  • 事件觸發。 這個模型與前面提到的模型完全不同。 它允許非常高的I / O並發性,因此非常適合長時間運行的阻塞I / O工作負載。 為了利用它,需要來自應用程序和框架的明確支持。 然而,像Rails和Sinatra這樣的所有主要框架都不支持均衡代碼。 這就是為什麼在實踐中,精簡流程仍然無法同時處理超過1個請求,使其與單線程多進程模型的行為效果相同。 有專門的框架可以利用均勻的I / O,比如Cramp。

最近在Phusion博客上發布了一篇關於優化調整工作負載的進程和線程數量的文章。 請參閱調整Phusion Passenger的並發設置

Capistrano的

卡皮斯特拉諾是完全不同的東西。 在前面的所有章節中,“部署”是指在應用程序服務器中啟動Ruby應用程序的行為,以便訪問者可以訪問它,但在此之前,通常需要做一些準備工作,例如:

  • 將Ruby應用程序的代碼和文件上傳到服務器機器。
  • 安裝你的應用依賴的庫。
  • 設置或遷移數據庫。
  • 啟動和停止應用程序可能依賴的任何守護程序,例如Sidekiq / Resque工作人員或其他人員。
  • 您在設置應用程序時需要完成的任何其他事情。

在Capistrano的情況下,“部署”是指做所有這些準備工作。 Capistrano不是應用程序服務器。 相反,它是使所有準備工作自動化的工具。 您可以告訴Capistrano您的服務器在哪裡,並且每次部署新版本的應用程序時都需要運行哪些命令,Capistrano會負責將Rails應用程序上傳到服務器並運行您指定的命令。

Capistrano總是與應用程序服務器結合使用。 它不會取代應用程序服務器。 反之亦然,應用服務器不會取代Capistrano,它們可以與Capistrano結合使用。

當然你不必使用Capistrano。 如果你喜歡用FTP上傳你的Ruby應用程序,並且每次都手動運行相同的命令步驟,那麼你可以做到這一點。 其他人對此感到厭倦,所以他們在Capistrano中自動執行這些步驟。





mongrel