Ruby on Rails Server-Optionen [geschlossen]

578

Das ganze Problem beim Einrichten eines Entwicklungsservers für meine Ruby on Rails-Anwendung verwirrt mich. Es gibt WEBrick, Mongrel, Passenger, Apache, Nginx und viele mehr, da bin ich mir sicher, und ich verstehe die verschiedenen Rollen, die sie spielen, nicht wirklich.

Ich habe angefangen, WEBrick zu verwenden, und jetzt verwende ich Mongrel für die Entwicklung. Sind diese Server eigenständig oder sitzen sie vor Apache?

Ich habe über Passenger gelesen und verstehe nicht wirklich, was es ist. Auf der Website heißt es "macht die Bereitstellung von Ruby-Webanwendungen zum Kinderspiel". Ersetzt sie Mongrel? Ist es wie Capistrano, das auch Webanwendungen bereitstellt?

Wenn ich bedenke, dass ich SSL testen möchte und ich glaube, dass dies von mongrel nicht unterstützt wird, was ist das beste Setup für Entwicklungsserver?

Vielen Dank

pingu
quelle
2
Haben Sie den Phusion Passenger Screencast gesehen? Es beschreibt in 5 Minuten alles, was Sie brauchen, um Ihre Rails-App online zu stellen.
Hongli
27
Für eine unkonstruktive Frage hat dies sicher viele positive Stimmen erhalten, ebenso wie die Antwort.
Teemu Leisti
32
Ich weiß, dass diese Frage gegen die Regeln von SO verstößt, aber ich frage mich, ob viele Benutzer diese Frage nützlich finden. Vielleicht ist es an der Zeit, einige Regeln zu ändern.
Hardik

Antworten:

1264

Das Wort "Bereitstellung" kann je nach Kontext zwei Bedeutungen haben. Sie verwechseln auch die Rollen von Apache / Nginx mit den Rollen anderer Komponenten.

Historischer Hinweis: Dieser Artikel wurde ursprünglich am 6. November 2010 verfasst, als das Ruby App Server-Ökosystem eingeschränkt war. Ich habe diesen Artikel am 15. März 2013 mit den neuesten Updates im Ökosystem aktualisiert.

Haftungsausschluss : Ich bin einer der Autoren von Phusion Passenger, einem der App-Server.

Apache gegen Nginx

Sie sind beide Webserver. Sie können statische Dateien bereitstellen, aber mit den richtigen Modulen auch dynamische Webanwendungen, z. B. solche, die in PHP geschrieben wurden. Apache ist beliebter und hat mehr Funktionen, Nginx ist kleiner und schneller und hat weniger Funktionen.

Weder Apache noch Nginx können Ruby-Web-Apps sofort bereitstellen. Dazu müssen Sie Apache / Nginx in Kombination mit einem später beschriebenen Add-On verwenden.

Apache und Nginx können auch als Reverse-Proxys fungieren. Dies bedeutet, dass sie eine eingehende HTTP-Anforderung entgegennehmen und an einen anderen Server weiterleiten können, der auch HTTP spricht. Wenn dieser Server mit einer HTTP-Antwort antwortet, leitet Apache / Nginx die Antwort an den Client zurück. Sie werden später erfahren, warum dies relevant ist.

Mongrel und andere Produktions-App-Server gegen WEBrick

Mongrel ist ein Ruby "Anwendungsserver": Konkret bedeutet dies, dass Mongrel eine Anwendung ist, die:

  1. Lädt Ihre Ruby-App in einen eigenen Prozessbereich.
  2. Richtet einen TCP-Socket ein, der die Kommunikation mit der Außenwelt (z. B. dem Internet) ermöglicht. Mongrel wartet auf HTTP-Anforderungen in diesem Socket und leitet die Anforderungsdaten an die Ruby-Webanwendung weiter.
  3. Die Ruby-Webanwendung gibt dann ein Objekt zurück, das beschreibt, wie die HTTP-Antwort aussehen soll, und Mongrel kümmert sich um die Konvertierung in eine tatsächliche HTTP-Antwort (die tatsächlichen Bytes) und sendet sie über den Socket zurück.

Obwohl Mongrel ziemlich veraltet ist, wird es heutzutage nicht mehr gepflegt. Neuere alternative Anwendungsserver sind:

  • Phusion Passagier
  • Einhorn
  • Dünn
  • Puma
  • Trinidad (nur JRuby)
  • TorqueBox (nur JRuby)

Ich werde sie später behandeln und beschreiben, wie sie sich voneinander und von Mongrel unterscheiden.

WEBrick macht dasselbe wie Mongrel, aber die Unterschiede sind:

  • WEBrick ist nicht produktionsfähig, im Gegensatz zu allem anderen, was ich zuvor erwähnt habe. WEBrick ist vollständig in Ruby geschrieben. Mongrel (und die meisten anderen Ruby-App-Server) sind Teil Ruby und Teil C (meistens Ruby), aber sein HTTP-Parser ist aus Leistungsgründen in C geschrieben.
  • WEBrick ist langsamer und weniger robust. Es sind einige Speicherlecks und einige bekannte HTTP-Analyseprobleme bekannt.
  • WEBrick wird normalerweise nur während der Entwicklung als Standardserver verwendet, da WEBrick standardmäßig in Ruby enthalten ist. Mongrel und andere App-Server müssen separat installiert werden. Es wird nicht empfohlen, WEBrick in Produktionsumgebungen zu verwenden, obwohl Heroku aus irgendeinem Grund WEBrick als Standardserver ausgewählt hat. Sie haben Thin schon einmal verwendet, daher habe ich keine Ahnung, warum sie zu WEBrick gewechselt sind.

Der App Server und die Welt

Alle aktuellen Ruby-App-Server sprechen HTTP. Einige App-Server sind jedoch möglicherweise direkt an Port 80 dem Internet ausgesetzt, andere möglicherweise nicht.

  • App-Server, die direkt dem Internet ausgesetzt werden können: Phusion Passenger, Rainbows
  • App-Server, die möglicherweise nicht direkt dem Internet ausgesetzt sind: Mongrel, Unicorn, Thin, Puma. Diese App-Server müssen hinter einem Reverse-Proxy-Webserver wie Apache und Nginx platziert werden.
  • Ich weiß nicht genug über Trinidad und TorqueBox, deshalb habe ich sie weggelassen.

Warum müssen einige App-Server hinter einen Reverse-Proxy gestellt werden?

  • Einige App-Server können nur 1 Anforderung gleichzeitig pro Prozess verarbeiten. Wenn Sie zwei Anforderungen gleichzeitig bearbeiten möchten, müssen Sie mehrere App-Server-Instanzen ausführen, die jeweils dieselbe Ruby-App bedienen. Diese Gruppe von App-Server-Prozessen wird als App-Server-Cluster bezeichnet (daher der Name Mongrel Cluster, Thin Cluster usw.). Sie müssen dann Apache oder Nginx einrichten, um den Proxy für diesen Cluster umzukehren. Apache / Nginx kümmert sich um die Verteilung der Anforderungen zwischen den Instanzen im Cluster (mehr dazu im Abschnitt "E / A-Parallelitätsmodelle").
  • Der Webserver kann Anforderungen und Antworten puffern und den App-Server vor "langsamen Clients" schützen - HTTP-Clients, die Daten nicht sehr schnell senden oder akzeptieren. Sie möchten nicht, dass Ihr App-Server nichts unternimmt, während er darauf wartet, dass der Client die vollständige Anfrage sendet oder die vollständige Antwort erhält, da der App-Server während dieser Zeit möglicherweise nichts anderes tun kann. Apache und Nginx sind sehr gut darin, viele Dinge gleichzeitig zu tun, da sie entweder Multithreading oder Evented sind.
  • Die meisten App-Server können statische Dateien bereitstellen, sind jedoch nicht besonders gut darin. Apache und Nginx können es schneller machen.
  • Normalerweise wird Apache / Nginx so eingerichtet, dass statische Dateien direkt bereitgestellt werden. Anfragen, die nicht mit statischen Dateien übereinstimmen, werden jedoch an den App-Server weitergeleitet. Dies ist eine gute Sicherheitspraxis. Apache und Nginx sind sehr ausgereift und können den App-Server vor (möglicherweise böswillig) beschädigten Anforderungen schützen.

Warum können einige App-Server direkt dem Internet ausgesetzt werden?

  • Phusion Passenger ist ein ganz anderes Tier als alle anderen App-Server. Eine seiner einzigartigen Eigenschaften ist die Integration in den Webserver.
  • Der Rainbows-Autor erklärte öffentlich, dass es sicher ist, es direkt dem Internet auszusetzen. Der Autor ist sich ziemlich sicher, dass der HTTP-Parser (und ähnliche) keine Sicherheitslücken aufweist. Der Autor gibt jedoch keine Garantie und sagt, dass die Verwendung auf eigenes Risiko erfolgt.

Anwendungsserver verglichen

In diesem Abschnitt werde ich die meisten Anwendungsserver vergleichen, die ich erwähnt habe, aber nicht Phusion Passenger. Phusion Passenger ist so ein anderes Tier als die anderen, dass ich ihm einen eigenen Abschnitt gegeben habe. Ich habe auch Trinidad und TorqueBox weggelassen, weil ich sie nicht gut genug kenne, aber sie sind sowieso nur relevant, wenn Sie JRuby verwenden.

  • Mischling war ziemlich nackt. Wie bereits erwähnt, handelt es sich bei Mongrel um einen reinen Single-Thread-Multiprozess, der nur in einem Cluster nützlich ist. Es gibt keine Prozessüberwachung: Wenn ein Prozess im Cluster abstürzt (z. B. aufgrund eines Fehlers in der App), muss er manuell neu gestartet werden. Menschen neigen dazu, externe Prozessüberwachungstools wie Monit und God zu verwenden.
  • Einhorn ist eine Gabel des Mischlings. Es unterstützt eine eingeschränkte Prozessüberwachung: Wenn ein Prozess abstürzt, wird er vom Masterprozess automatisch neu gestartet. Es kann dazu führen, dass alle Prozesse einen einzelnen gemeinsam genutzten Socket abhören, anstatt einen separaten Socket für jeden Prozess. Dies vereinfacht die Reverse-Proxy-Konfiguration. Wie Mongrel ist es ein reiner Single-Thread-Multiprozess.
  • Thin verwendet das ereignisgesteuerte E / A-Modell mithilfe der EventMachine-Bibliothek. Anders als der HTTP-Parser von Mongrel basiert er in keiner Weise auf Mongrel. Der Cluster-Modus verfügt über keine Prozessüberwachung, sodass Sie Abstürze usw. überwachen müssen. Es gibt keinen Einhorn-ähnlichen gemeinsam genutzten Socket, sodass jeder Prozess seinen eigenen Socket abhört. Theoretisch ermöglicht das E / A-Modell von Thin eine hohe Parallelität. In den meisten praktischen Situationen, für die Thin verwendet wird, kann ein Thin-Prozess jedoch nur eine gleichzeitige Anforderung verarbeiten, sodass Sie weiterhin einen Cluster benötigen. Weitere Informationen zu dieser besonderen Eigenschaft finden Sie im Abschnitt "E / A-Parallelitätsmodelle".
  • Puma wurde ebenfalls von Mongrel gegabelt, aber im Gegensatz zu Unicorn ist Puma so konzipiert, dass es nur aus mehreren Threads besteht. Daher gibt es derzeit keine integrierte Clusterunterstützung. Sie müssen besonders darauf achten, dass Sie mehrere Kerne verwenden können (mehr dazu im Abschnitt "E / A-Parallelitätsmodelle").
  • Rainbows unterstützt mehrere Parallelitätsmodelle durch die Verwendung verschiedener Bibliotheken.

Phusion Passagier

Phusion Passenger arbeitet ganz anders als alle anderen. Phusion Passenger lässt sich direkt in Apache oder Nginx integrieren und kann daher mit mod_php für Apache verglichen werden. Genau wie mod_php es Apache ermöglicht, PHP-Apps fast magisch zu bedienen, erlaubt Phusion Passenger Apache (und auch Nginx!), Ruby-Apps fast magisch zu bedienen. Das Ziel von Phusion Passenger ist es, alles so einfach wie möglich zu gestalten.

Anstatt einen Prozess oder Cluster für Ihre App zu starten und Apache / Nginx so zu konfigurieren, dass statische Dateien bereitgestellt und / oder Proxy-Anforderungen mit Phusion Passenger an den Prozess / Cluster umgekehrt werden, müssen Sie nur:

  1. Sie bearbeiten die Webserver-Konfigurationsdatei und geben den Speicherort des öffentlichen Verzeichnisses Ihrer Ruby-App an.
  2. Es gibt keinen Schritt 2.

Die gesamte Konfiguration erfolgt in der Webserver-Konfigurationsdatei. Phusion Passenger automatisiert so ziemlich alles. Es ist nicht erforderlich, einen Cluster zu starten und Prozesse zu verwalten. Starten / Stoppen von Prozessen, Neustarten bei einem Absturz usw. - alles automatisiert. Im Vergleich zu anderen App-Servern hat Phusion Passenger weit weniger bewegliche Teile. Diese Benutzerfreundlichkeit ist einer der Hauptgründe, warum Menschen Phusion Passenger verwenden.

Auch im Gegensatz zu anderen App-Servern ist Phusion Passenger hauptsächlich in C ++ geschrieben, was es sehr schnell macht.

Es gibt auch eine Enterprise-Variante von Phusion Passenger mit noch mehr Funktionen wie automatisierten Rolling-Neustarts, Multithreading-Unterstützung, Beständigkeit gegen Bereitstellungsfehler usw.

Aus den oben genannten Gründen ist Phusion Passenger derzeit der beliebteste Ruby-App-Server und versorgt über 150.000 Websites, darunter große wie die New York Times, Pixar, Airbnb usw.

Phusion Passenger gegen andere App-Server

Phusion Passenger bietet viel mehr Funktionen und viele Vorteile gegenüber anderen App-Servern, wie z.

  • Dynamische Anpassung der Anzahl der Prozesse basierend auf dem Datenverkehr. Wir führen eine Menge Rails-Apps auf unserem Server mit eingeschränkten Ressourcen aus, die nicht öffentlich zugänglich sind und die von den Mitarbeitern unserer Organisation höchstens einige Male am Tag verwendet werden. Dinge wie Gitlab, Redmine usw. Phusion Passenger kann diese Prozesse herunterfahren, wenn sie nicht verwendet werden, und sie hochfahren, wenn sie verwendet werden, sodass mehr Ressourcen für wichtigere Apps verfügbar sind. Bei anderen App-Servern sind alle Ihre Prozesse ständig aktiviert.
  • Einige App-Server sind von Natur aus nicht für bestimmte Workloads geeignet. Zum Beispiel ist Unicorn nur für schnell laufende Anfragen konzipiert: Siehe den Abschnitt "In einigen Fällen nur schlimmer" auf der Unicorn-Website .

Arbeitslasten, in denen Unicorn nicht gut ist, sind:

  • Streaming-Workloads (z. B. Rails 4-Live-Streaming oder Rails 4-Vorlagen-Streaming).
  • Workloads, bei denen die App HTTP-API-Aufrufe ausführt.

Das Hybrid-E / A-Modell in Phusion Passenger Enterprise 4 oder höher macht es zu einer hervorragenden Wahl für diese Art von Workloads.

  • Bei anderen App-Servern muss der Benutzer mindestens eine Instanz pro Anwendung ausführen. Im Gegensatz dazu unterstützt Phusion Passenger mehrere Anwendungen in einer einzigen Instanz. Dies reduziert den Verwaltungsaufwand erheblich.
  • Automatische Benutzerumschaltung, eine praktische Sicherheitsfunktion.
  • Phusion Passenger unterstützt viele MRT Ruby, JRuby und Rubinius. Mischling, Einhorn und Dünn unterstützen nur die MRT. Puma unterstützt auch alle 3.
  • Phusion Passenger unterstützt tatsächlich mehr als nur Ruby! Es unterstützt auch Python WSGI, so dass beispielsweise auch Django- und Flask-Apps ausgeführt werden können. Tatsächlich bewegt sich Phusion Passenger in Richtung eines polyglotten Servers. Node.js Unterstützung auf der Aufgabenliste.
  • Out-of-Band-Speicherbereinigung. Phusion Passenger kann den Ruby-Garbage-Collector außerhalb des normalen Anforderungs- / Antwortzyklus ausführen, wodurch die Anforderungszeiten möglicherweise um Hunderte von Millisekunden verkürzt werden. Unicorn hat auch eine ähnliche Funktion, aber die Version von Phusion Passenger ist flexibler, weil 1) sie nicht auf GC beschränkt ist und für beliebige Arbeiten verwendet werden kann. 2) Die Version von Phusion Passenger funktioniert gut mit Multithread-Apps, die von Unicorn nicht.
  • Automatischer Neustart. Rollende Neustarts auf Unicorn und anderen Servern erfordern einige Skriptarbeiten. Phusion Passenger Enterprise automatisiert diesen Weg für Sie vollständig.

Es gibt mehr Funktionen und Vorteile, aber die Liste ist wirklich lang. Weitere Informationen finden Sie im umfassenden Phusion Passenger-Handbuch ( Apache-Version , Nginx-Version ) oder auf der Phusion Passenger-Website .

E / A-Parallelitätsmodelle

  • Single-Threaded-Multiprozess. Dies ist traditionell das beliebteste E / A-Modell für Ruby-App-Server, teilweise weil die Multithreading-Unterstützung im Ruby-Ökosystem sehr schlecht war. Jeder Prozess kann jeweils genau eine Anforderung verarbeiten. Der Lastenausgleich des Webservers zwischen den Prozessen. Dieses Modell ist sehr robust und es gibt kaum eine Chance für den Programmierer, Parallelitätsfehler einzuführen. Die E / A-Parallelität ist jedoch äußerst begrenzt (begrenzt durch die Anzahl der Prozesse). Dieses Modell eignet sich sehr gut für schnelle, kurz laufende Workloads. Es ist sehr ungeeignet für langsame, lang laufende blockierende E / A-Workloads, z. B. Workloads, bei denen HTTP-APIs aufgerufen werden.
  • Rein multithreaded. Heutzutage bietet das Ruby-Ökosystem eine hervorragende Multithreading-Unterstützung, sodass dieses E / A-Modell sehr praktikabel geworden ist. Multithreading ermöglicht eine hohe E / A-Parallelität und eignet sich daher sowohl für kurz- als auch für lang laufende blockierende E / A-Workloads. Es ist wahrscheinlicher, dass der Programmierer Parallelitätsfehler einführt, aber zum Glück sind die meisten Web-Frameworks so konzipiert, dass dies immer noch sehr unwahrscheinlich ist. Zu beachten ist jedoch, dass der MRI Ruby-Interpreter aufgrund der Verwendung der globalen Interpreter-Sperre (GIL) nicht mehrere CPU-Kerne nutzen kann, selbst wenn mehrere Threads vorhanden sind. Sie können dies umgehen, indem Sie mehrere Multithread-Prozesse verwenden, da jeder Prozess einen CPU-Kern nutzen kann. JRuby und Rubinius haben keine GIL, sodass sie mehrere Kerne in einem einzigen Prozess vollständig nutzen können.
  • Hybrid-Multithread-Multiprozess. Hauptsächlich implementiert von Phusion Passenger Enterprise 4 und höher. Sie können problemlos zwischen Single-Threaded-Multiprozessen, reinen Multithread-Prozessen oder sogar mehreren Prozessen mit jeweils mehreren Threads wechseln. Dieses Modell bietet das Beste aus beiden Welten.
  • Evented. Dieses Modell unterscheidet sich grundlegend von dem zuvor erwähnten Modell. Es ermöglicht eine sehr hohe E / A-Parallelität und eignet sich daher hervorragend für lange laufende blockierende E / A-Workloads. Um es nutzen zu können, ist eine explizite Unterstützung durch die Anwendung und das Framework erforderlich. Alle wichtigen Frameworks wie Rails und Sinatra unterstützen jedoch keinen ereignisreichen Code. Aus diesem Grund kann ein Thin-Prozess in der Praxis immer noch nicht mehr als eine Anforderung gleichzeitig verarbeiten, sodass er sich effektiv wie das Single-Threaded-Multiprozessmodell verhält. Es gibt spezielle Frameworks, die ereignisgesteuerte E / A nutzen können, z. B. Cramp.

Kürzlich wurde im Phusion-Blog ein Artikel veröffentlicht, in dem es darum geht, die Anzahl der Prozesse und Threads angesichts Ihrer Arbeitslast optimal zu optimieren. Siehe Einstellen der Parallelitätseinstellungen von Phusion Passenger .

Capistrano

Capistrano ist etwas ganz anderes. In allen vorherigen Abschnitten bezieht sich "Bereitstellung" auf das Starten Ihrer Ruby-App auf einem Anwendungsserver, damit sie für Besucher zugänglich wird. Bevor dies jedoch geschehen kann, müssen in der Regel einige Vorbereitungsarbeiten durchgeführt werden, z.

  • Hochladen des Codes und der Dateien der Ruby-App auf den Server.
  • Das Installieren von Bibliotheken, von denen Ihre App abhängt.
  • Einrichten oder Migrieren der Datenbank.
  • Starten und Stoppen von Daemons, auf die sich Ihre App möglicherweise verlässt, z. B. Sidekiq / Resque-Mitarbeiter oder was auch immer.
  • Alle anderen Dinge, die beim Einrichten Ihrer Anwendung erledigt werden müssen.

Im Kontext von Capistrano bezieht sich "Bereitstellung" auf all diese Vorbereitungsarbeiten. Capistrano ist kein Anwendungsserver. Stattdessen ist es ein Werkzeug zur Automatisierung all dieser Vorbereitungsarbeiten. Sie teilen Capistrano bei jeder Bereitstellung einer neuen Version Ihrer App mit, wo sich Ihr Server befindet und welche Befehle ausgeführt werden müssen, und Capistrano kümmert sich darum, die Rails-App für Sie auf den Server hochzuladen und die von Ihnen angegebenen Befehle auszuführen.

Capistrano wird immer in Kombination mit einem Anwendungsserver verwendet. Es ersetzt keine Anwendungsserver. Umgekehrt ersetzen Anwendungsserver Capistrano nicht, sondern können in Kombination mit Capistrano verwendet werden.

Natürlich müssen Sie nicht haben zu Capistrano verwenden. Wenn Sie Ihre Ruby-App lieber mit FTP hochladen und jedes Mal dieselben Befehlsschritte manuell ausführen möchten, können Sie dies tun. Andere Leute haben es satt und automatisieren diese Schritte in Capistrano.

Hongli
quelle
74
Sie sollten dies irgendwo veröffentlichen. Es ist jetzt alles einfach, aber als ich mit Schienen anfing, war es schwierig, nützliche Informationen zu bekommen.
Spegoraro
9
Ausgezeichnete Post! Auch für mich viel geklärt. Sie sollten einige andere Elemente wie Bundler und RVM hinzufügen und daraus einen schlagkräftigen Blog-Beitrag machen! :)
Damien Roche
37
Dies muss in den Rails-Handbüchern enthalten sein.
Dorian
4
"Niemand verwendet WEBrick in Produktionsumgebungen." Dies ist überhaupt nicht wahr. Der Standard-App-Server beim Verschieben von Ruby-Apps an Heroku ist Webrick.
John Downey
37
@ Hongli Dieser Beitrag ist sehr günstig für Phusion Passenger. Vielleicht wäre es aus Gründen der Objektivität ratsam , Ihre Zugehörigkeit zum Projekt (CTO, phusion.nl/about ) hinzuzufügen ?
Bert Goethals