Opcje serwera Ruby on Rails [zamknięte]

578

Cały problem konfigurowania serwera programistycznego dla mojej aplikacji Ruby on Rails dezorientuje mnie. Są WEBrick, Mongrel, Passenger, Apache, Nginx i wiele innych, jestem pewien, i tak naprawdę nie rozumiem różnych ról, jakie odgrywają.

Zaczynałem od WEBrick, a teraz używam Mongrel do programowania. Czy te serwery są samodzielne, czy też stoją przed Apache?

Przeczytałem o Passenger i naprawdę nie rozumiem, co to jest, strona mówi „sprawia, że ​​wdrażanie aplikacji internetowych Ruby jest dziecinnie proste”, czy to zastępuje Mongrel? Czy to jak Capistrano, który także wdraża aplikacje internetowe?

Mając na uwadze, że chciałbym przetestować SSL i uważam, że nie obsługuje go kundel, jaka jest najlepsza konfiguracja serwera programistycznego?

Dzięki

pingu
źródło
2
Czy oglądałeś screen z Phusion Passenger? Opisuje prawie w 5 minut wszystko, czego potrzeba, aby przełączyć aplikację Rails do trybu online.
Hongli,
27
Jeśli chodzi o niekonstruktywne pytanie, to z pewnością zyskało wiele pozytywnych opinii, podobnie jak odpowiedź.
Teemu Leisti,
32
Wiem, że to pytanie łamie zasady SO, ale zastanawiam się, czy wielu użytkowników uważa to pytanie za przydatne, może czas zmodyfikować niektóre reguły?
Hardik

Odpowiedzi:

1264

Słowo „wdrożenie” może mieć dwa znaczenia w zależności od kontekstu. Mylisz także role Apache / Nginx z rolami innych komponentów.

Uwaga historyczna: ten artykuł został pierwotnie napisany 6 listopada 2010 r., Kiedy ekosystem serwera aplikacji Ruby był ograniczony. Zaktualizowałem ten artykuł 15 marca 2013 r. Wszystkimi najnowszymi aktualizacjami w ekosystemie.

Oświadczenie : Jestem jednym z autorów Phusion Passenger, jednego z serwerów aplikacji.

Apache vs Nginx

Oba serwery WWW. Mogą obsługiwać pliki statyczne, ale - z odpowiednimi modułami - mogą także obsługiwać dynamiczne aplikacje internetowe, np. Te napisane w PHP. Apache jest bardziej popularny i ma więcej funkcji, Nginx jest mniejszy i szybszy oraz ma mniej funkcji.

Ani Apache, ani Nginx nie mogą obsługiwać aplikacji internetowych Ruby od razu po wyjęciu z pudełka, aby to zrobić, musisz użyć Apache / Nginx w połączeniu z jakimś dodatkiem opisanym później.

Apache i Nginx mogą również działać jako odwrotne serwery proxy, co oznacza, że ​​mogą przyjmować przychodzące żądania HTTP i przekazywać je na inny serwer, który również obsługuje HTTP. Gdy serwer odpowie odpowiedzią HTTP, Apache / Nginx prześle odpowiedź z powrotem do klienta; Dowiesz się później, dlaczego jest to istotne.

Mongrel i inne serwery aplikacji produkcyjnych vs WEBrick

Mongrel to Ruby „serwer aplikacji”: Konkretnie oznacza to, że Mongrel to aplikacja, która:

  1. Ładuje aplikację Ruby w jej własnej przestrzeni procesu.
  2. Konfiguruje gniazdo TCP, pozwalając mu komunikować się ze światem zewnętrznym (np. Internetem). Mongrel nasłuchuje żądań HTTP na tym gnieździe i przekazuje dane żądania do aplikacji internetowej Ruby.
  3. Następnie aplikacja internetowa Ruby zwraca obiekt, który opisuje, jak powinna wyglądać odpowiedź HTTP, a Mongrel zajmuje się konwertowaniem jej na rzeczywistą odpowiedź HTTP (rzeczywiste bajty) i wysyła ją z powrotem przez gniazdo.

Jednak Mongrel jest dość przestarzały, obecnie nie jest już utrzymywany. Nowsze alternatywne serwery aplikacji to:

  • Phusion Passenger
  • Jednorożec
  • Chudy
  • Puma
  • Trynidad (tylko JRuby)
  • TorqueBox (tylko JRuby)

Omówię je później i opiszę, jak różnią się od siebie i od Mongrel.

WEBrick robi to samo co Mongrel, ale różnice są następujące:

  • WEBrick nie nadaje się do produkcji, w przeciwieństwie do wszystkiego, co wspomniałem wcześniej. WEBrick jest napisany całkowicie w języku Ruby. Mongrel (i większość innych serwerów aplikacji Ruby) jest częścią Ruby i częścią C (głównie Ruby), ale jego parser HTTP jest napisany w C dla wydajności.
  • WEBrick jest wolniejszy i mniej niezawodny. Ma pewne znane wycieki pamięci i znane problemy z analizą HTTP.
  • WEBrick jest zwykle używany tylko jako domyślny serwer podczas programowania, ponieważ WEBrick jest domyślnie dołączony do Rubiego. Kundel i inne serwery aplikacji należy zainstalować osobno. Nie zaleca się używania WEBrick w środowiskach produkcyjnych, choć z jakiegoś powodu Heroku wybrał WEBrick jako domyślny serwer. Używali wcześniej Thin, więc nie mam pojęcia, dlaczego przestawili się na WEBrick.

Serwer aplikacji i świat

Wszystkie obecne serwery aplikacji Ruby mówią HTTP, jednak niektóre serwery aplikacji mogą być bezpośrednio narażone na działanie Internetu na porcie 80, a inne nie.

  • Serwery aplikacji, które mogą być bezpośrednio dostępne w Internecie: Phusion Passenger, Rainbows
  • Serwery aplikacji, które nie mogą być bezpośrednio narażone na działanie Internetu: Mongrel, Unicorn, Thin, Puma. Te serwery aplikacji muszą znajdować się za odwrotnym serwerem proxy, takim jak Apache i Nginx.
  • Nie wiem wystarczająco dużo o Trynidadzie i TorqueBox, więc je pominąłem.

Dlaczego niektóre serwery aplikacji muszą znajdować się za odwrotnym proxy?

  • Niektóre serwery aplikacji mogą obsłużyć tylko 1 żądanie na proces. Jeśli chcesz obsłużyć 2 żądania jednocześnie, musisz uruchomić wiele instancji serwera aplikacji, z których każda obsługuje tę samą aplikację Ruby. Ten zestaw procesów serwera aplikacji jest nazywany klastrem serwerów aplikacji (stąd nazwa Mongrel Cluster, Thin Cluster itp.). Następnie musisz skonfigurować Apache lub Nginx, aby odwrócić proxy do tego klastra. Apache / Nginx zajmie się dystrybucją żądań między instancjami w klastrze (więcej na ten temat w sekcji „Modele współbieżności we / wy”).
  • Serwer WWW może buforować żądania i odpowiedzi, chroniąc serwer aplikacji przed „powolnymi klientami” - klientami HTTP, którzy nie wysyłają lub nie akceptują danych bardzo szybko. Nie chcesz, aby serwer aplikacji nic nie robił, czekając, aż klient wyśle ​​pełne żądanie lub otrzyma pełną odpowiedź, ponieważ w tym czasie serwer aplikacji może nie być w stanie nic zrobić. Apache i Nginx są bardzo dobrzy w robieniu wielu rzeczy jednocześnie, ponieważ są albo wielowątkowe, albo zdarzone.
  • Większość serwerów aplikacji może obsługiwać pliki statyczne, ale nie jest w tym szczególnie dobra. Apache i Nginx mogą to zrobić szybciej.
  • Ludzie zwykle konfigurują Apache / Nginx do obsługi plików statycznych bezpośrednio, ale przesyłają żądania, które nie odpowiadają plikom statycznym do serwera aplikacji, to dobra praktyka bezpieczeństwa. Apache i Nginx są bardzo dojrzałe i mogą chronić serwer aplikacji przed (być może złośliwie) uszkodzonymi żądaniami.

Dlaczego niektóre serwery aplikacji mogą być bezpośrednio dostępne w Internecie?

  • Phusion Passenger to zupełnie inna bestia od wszystkich innych serwerów aplikacji. Jedną z jego unikalnych cech jest integracja z serwerem WWW.
  • Autor Rainbows publicznie stwierdził, że bezpieczne jest bezpośrednie udostępnianie go w Internecie. Autor jest całkiem pewien, że nie ma żadnych luk w parserze HTTP (i podobnych). Mimo to autor nie udziela żadnej gwarancji i twierdzi, że użytkowanie odbywa się na własne ryzyko.

Porównanie serwerów aplikacji

W tej sekcji porównam większość serwerów aplikacji, o których wspomniałem, ale nie Phusion Passenger. Phusion Passenger to tak inna bestia niż reszta, że ​​poświęciłem jej specjalną sekcję. Pominąłem także Trynidad i TorqueBox, ponieważ nie znam ich wystarczająco dobrze, ale i tak są one istotne tylko, jeśli używasz JRuby.

  • Kundel miał całkiem nagie kości. Jak wspomniano wcześniej, Mongrel jest czysto jednowątkowym wieloprocesowym, więc jest użyteczny tylko w klastrze. Nie ma monitorowania procesu: jeśli proces w klastrze ulega awarii (np. Z powodu błędu w aplikacji), należy go ręcznie uruchomić ponownie. Ludzie używają zewnętrznych narzędzi do monitorowania procesów, takich jak Monit i Bóg.
  • Jednorożec to widelec kundla. Obsługuje ograniczone monitorowanie procesu: jeśli proces ulegnie awarii, zostanie automatycznie ponownie uruchomiony przez proces główny. Może sprawić, że wszystkie procesy będą nasłuchiwać na jednym współużytkowanym gnieździe zamiast na osobnym gnieździe dla każdego procesu. Upraszcza to konfigurację odwrotnego proxy. Podobnie jak Mongrel, jest to czysto jednowątkowy proces wieloprocesowy.
  • Thin używa modelu zdarzeń we / wy za pomocą biblioteki EventMachine. Poza użyciem parsera HTTP Mongrel, nie jest w żaden sposób oparty na Mongrel. Tryb klastra nie ma monitorowania procesu, więc musisz monitorować awarie itp. Nie ma wspólnego gniazda podobnego do Jednorożca, więc każdy proces nasłuchuje na swoim własnym gnieździe. Teoretycznie model We / Wy Thina pozwala na wysoką współbieżność, ale w większości praktycznych sytuacji, w których wykorzystywany jest Thin, jeden proces Thin może obsłużyć tylko 1 współbieżne żądanie, więc nadal potrzebujesz klastra. Więcej informacji na temat tej szczególnej właściwości w sekcji „Modele współbieżności we / wy”.
  • Puma została również rozwidlona z Mongrel, ale w przeciwieństwie do Unicorn, Puma została zaprojektowana z myślą o wielowątkowości. Dlatego obecnie nie ma wbudowanej obsługi klastra. Należy zachować szczególną ostrożność, aby zapewnić możliwość korzystania z wielu rdzeni (więcej na ten temat w sekcji „Modele współbieżności we / wy”).
  • Rainbows obsługuje wiele modeli współbieżności za pomocą różnych bibliotek.

Phusion Passenger

Phusion Passenger działa zupełnie inaczej niż wszystkie pozostałe. Phusion Passenger integruje się bezpośrednio z Apache lub Nginx, a więc można go porównać do mod_php dla Apache. Podobnie jak mod_php pozwala Apache'owi na obsługę aplikacji PHP niemal magicznie, Phusion Passenger pozwala Apache (a także Nginx!) Na obsługę aplikacji Ruby, prawie magicznie. Celem Phusion Passenger jest sprawienie, aby wszystko działało jak najlepiej (tm) przy jak najmniejszym wysiłku.

Zamiast uruchamiać proces lub klaster dla swojej aplikacji i konfigurować Apache / Nginx do obsługi plików statycznych i / lub odwrotnych żądań proxy do procesu / klastra za pomocą Phusion Passenger, wystarczy:

  1. Edytujesz plik konfiguracyjny serwera WWW i określasz lokalizację „publicznego” katalogu swojej aplikacji Ruby.
  2. Nie ma kroku 2.

Cała konfiguracja odbywa się w pliku konfiguracyjnym serwera WWW. Phusion Passenger automatyzuje prawie wszystko. Nie ma potrzeby uruchamiania klastra i zarządzania procesami. Uruchamianie / zatrzymywanie procesów, restartowanie ich po awarii itp. - wszystko zautomatyzowane. W porównaniu do innych serwerów aplikacji, Phusion Passenger ma znacznie mniej części ruchomych. Ta łatwość użytkowania jest jednym z głównych powodów, dla których ludzie korzystają z Phusion Passenger.

Również w przeciwieństwie do innych serwerów aplikacji, Phusion Passenger jest napisany głównie w C ++, dzięki czemu jest bardzo szybki.

Istnieje również wariant Enterprise Phusion Passenger z jeszcze większymi funkcjami, takimi jak automatyczne automatyczne restartowanie, obsługa wielowątkowości, odporność na błędy wdrażania itp.

Z powyższych powodów Phusion Passenger jest obecnie najpopularniejszym serwerem aplikacji Ruby, obsługującym ponad 150 000 stron internetowych, w tym duże, takie jak New York Times, Pixar, Airbnb itp.

Phusion Passenger vs. inne serwery aplikacji

Phusion Passenger zapewnia o wiele więcej funkcji i zapewnia wiele korzyści w stosunku do innych serwerów aplikacji, takich jak:

  • Dynamiczne dostosowywanie liczby procesów na podstawie ruchu. Na naszym serwerze z ograniczonymi zasobami uruchamiamy mnóstwo aplikacji Rails, które nie są dostępne publicznie, a ludzie w naszej organizacji używają ich najwyżej kilka razy dziennie. Takie rzeczy jak Gitlab, Redmine itp. Phusion Passenger może spowolnić te procesy, gdy nie są używane, i rozkręcić je, gdy są używane, umożliwiając dostęp do większej ilości zasobów dla ważniejszych aplikacji. W przypadku innych serwerów aplikacji wszystkie procesy są cały czas włączone.
  • Niektóre serwery aplikacji z założenia nie są dobre w przypadku niektórych obciążeń. Na przykład Unicorn jest przeznaczony tylko do szybkich żądań: patrz sekcja witryny Unicorn „Po prostu gorzej w niektórych przypadkach”.

Obciążenia, w których Unicorn nie jest dobry, to:

  • Obciążenia strumieniowe (np. Strumieniowanie na żywo w Railsach 4 lub strumieniowanie szablonów w Railsach 4).
  • Obciążenia, w których aplikacja wykonuje wywołania API HTTP.

Hybrydowy model I / O w Phusion Passenger Enterprise 4 lub nowszy sprawia, że ​​jest doskonałym wyborem do tego rodzaju obciążeń.

  • Inne serwery aplikacji wymagają od użytkownika uruchomienia co najmniej jednej instancji na aplikację. Z kolei Phusion Passenger obsługuje wiele aplikacji w jednym wystąpieniu. To znacznie zmniejsza koszty administracyjne.
  • Automatyczne przełączanie użytkowników, wygodna funkcja bezpieczeństwa.
  • Phusion Passenger obsługuje wiele MRI Ruby, JRuby i Rubinius. Kundel, Jednorożec i Cienki obsługują tylko MRI. Puma obsługuje również wszystkie 3.
  • Phusion Passenger w rzeczywistości obsługuje więcej niż tylko Ruby! Obsługuje również Python WSGI, więc może na przykład również uruchamiać aplikacje Django i Flask. W rzeczywistości Phusion Passenger zmierza w kierunku zostania serwerem polyglot. Obsługa Node.js na liście zadań.
  • Pozapasmowe zbieranie śmieci. Phusion Passenger może uruchomić moduł śmieciowy Ruby poza normalnym cyklem żądania / odpowiedzi, potencjalnie skracając czas żądania o setki milisekund. Unicorn ma również podobną funkcję, ale wersja Phusion Passenger jest bardziej elastyczna, ponieważ 1) nie jest ograniczona do GC i może być używana do dowolnej pracy. 2) Wersja Phusion Passenger działa dobrze z aplikacjami wielowątkowymi, a Unicorn nie.
  • Zautomatyzowane ponowne uruchamianie. Rolling restartuje się na Unicorn i innych serwerach, wymaga trochę pracy skryptowej. Phusion Passenger Enterprise całkowicie zautomatyzuje to dla Ciebie.

Jest więcej funkcji i zalet, ale lista jest naprawdę długa. Należy odnieść się do kompleksowej obsługi Phusion pasażera ( Apache , wersja Nginx ) lub stronie pasażera Phusion celach informacyjnych.

Modele współbieżności we / wy

  • Jednowątkowy wieloprocesowy. Jest to tradycyjnie najpopularniejszy model we / wy dla serwerów aplikacji Ruby, częściowo dlatego, że obsługa wielowątkowości w ekosystemie Ruby była bardzo zła. Każdy proces może obsłużyć dokładnie 1 żądanie na raz. Bilans obciążenia serwera WWW między procesami. Ten model jest bardzo solidny i programiści mają niewielkie szanse na wprowadzenie błędów współbieżności. Jednak jego współbieżność operacji we / wy jest bardzo ograniczona (ograniczona liczbą procesów). Ten model jest bardzo odpowiedni do szybkich, krótkotrwałych obciążeń. Jest to bardzo nieodpowiednie dla powolnych, długo działających blokujących obciążeń We / Wy, np. Obciążeń obejmujących wywołanie interfejsów API HTTP.
  • Czysto wielowątkowy. Obecnie ekosystem Ruby ma doskonałą obsługę wielowątkowości, więc ten model I / O stał się bardzo opłacalny. Wielowątkowość pozwala na wysoką współbieżność operacji we / wy, dzięki czemu nadaje się zarówno do krótkotrwałych, jak i długotrwałych blokujących obciążeń we / wy. Jest bardziej prawdopodobne, że programiści wprowadzą błędy współbieżności, ale na szczęście większość platform internetowych jest zaprojektowana w taki sposób, że jest to nadal bardzo mało prawdopodobne. Należy jednak zauważyć, że interpreter MRI Ruby nie może wykorzystywać wielu rdzeni procesora, nawet gdy istnieje wiele wątków, ze względu na użycie Global Interpreter Lock (GIL). Można obejść ten problem, używając wielu procesów wielowątkowych, ponieważ każdy proces może wykorzystywać rdzeń procesora. JRuby i Rubinius nie mają GIL, więc mogą w pełni wykorzystać wiele rdzeni w jednym procesie.
  • Hybrydowy wielowątkowy wieloprocesowy. Głównie zaimplementowane przez Phusion Passenger Enterprise 4 i późniejsze. Możesz łatwo przełączać się między jednowątkowym wieloprocesowym, czysto wielowątkowym, a może nawet wieloma procesami z wieloma wątkami. Ten model daje to, co najlepsze z obu światów.
  • Evented. Ten model różni się całkowicie od wcześniej wspomnianego modelu. Umożliwia bardzo wysoką współbieżność operacji we / wy, a zatem jest doskonała do długotrwałego blokowania obciążeń operacji we / wy. Aby go wykorzystać, wymagana jest wyraźna obsługa aplikacji i frameworka. Jednak wszystkie główne frameworki, takie jak Rails i Sinatra, nie obsługują kodu zdarzenia. Dlatego w praktyce cienki proces nadal nie może obsłużyć więcej niż 1 żądania na raz, dzięki czemu zachowuje się tak samo jak model wielowątkowy jednowątkowy. Istnieją wyspecjalizowane frameworki, które mogą wykorzystywać zdarzenia I / O, takie jak Cramp.

Niedawno opublikowano artykuł na blogu Phusion o optymalnym dostosowaniu liczby procesów i wątków do obciążenia. Zobacz Strojenie ustawień współbieżności Phusion Passenger .

Capistrano

Capistrano to coś zupełnie innego. We wszystkich poprzednich sekcjach „wdrożenie” odnosi się do uruchomienia aplikacji Ruby na serwerze aplikacji, aby stała się dostępna dla odwiedzających, ale zanim to nastąpi, zwykle trzeba wykonać pewne czynności przygotowawcze, takie jak:

  • Przesyłanie kodu i plików aplikacji Ruby na serwer.
  • Instalowanie bibliotek, od których zależy twoja aplikacja.
  • Konfigurowanie lub migrowanie bazy danych.
  • Uruchamianie i zatrzymywanie dowolnych demonów, na których aplikacja może polegać, takich jak pracownicy Sidekiq / Resque lub cokolwiek innego.
  • Wszelkie inne czynności, które należy wykonać podczas konfigurowania aplikacji.

W kontekście Capistrano „wdrożenie” odnosi się do wykonania wszystkich tych prac przygotowawczych. Capistrano nie jest serwerem aplikacji. Zamiast tego jest to narzędzie do automatyzacji wszystkich prac przygotowawczych. Poinformujesz Capistrano, gdzie jest twój serwer i jakie polecenia należy uruchamiać za każdym razem, gdy wdrażasz nową wersję aplikacji, a Capistrano zajmie się przesłaniem aplikacji Rails na serwer i uruchomieniem określonych poleceń.

Capistrano jest zawsze używany w połączeniu z serwerem aplikacji. Nie zastępuje serwerów aplikacji. Odwrotnie, serwery aplikacji nie zastępują Capistrano, można ich używać w połączeniu z Capistrano.

Oczywiście nie musisz używać Capistrano. Jeśli wolisz przesłać swoją aplikację Ruby za pomocą FTP i ręcznie uruchamiać te same kroki poleceń za każdym razem, możesz to zrobić. Inni ludzie zmęczyli się tym, więc automatyzują te kroki w Capistrano.

Hongli
źródło
74
Powinieneś to gdzieś opublikować. Teraz wszystko jest łatwe, ale kiedy zaczynałem od szyn, trudno było uzyskać przydatne informacje.
spegoraro
9
Doskonały post! Dla mnie też wiele się wyjaśniło. Powinieneś dodać kilka innych elementów, takich jak bundler i rvm, i uczynić z niego popularnego posta na blogu! :)
Damien Roche
37
To musi być w przewodnikach po Railsach.
Dorian
4
„Nikt nie używa WEBrick w środowiskach produkcyjnych”. To wcale nie jest prawda. Domyślnym serwerem aplikacji podczas wypychania aplikacji ruby ​​do heroku jest webrick.
John Downey,
37
@Hongli Ten post jest bardzo korzystny dla Phusion Passenger. Może warto dodać swoją przynależność do projektu (CTO, phusion.nl/about ) ze względu na obiektywizm?
Bert Goethals