ruby-on-rails - program - passenger web server



Ruby on Rails Server Optionen (1)

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

Ich begann mit WEBrick und jetzt benutze ich Mongrel für die Entwicklung. Sind diese Server eigenständig oder sitzen sie vor Apache?

Ich habe über Passenger gelesen und ich verstehe nicht wirklich, was es ist, die Seite sagt "macht den Einsatz von Ruby-Web-Anwendungen zum Kinderspiel", ersetzt es Mongrel? Ist es wie Capistrano, der auch Web-Anwendungen einsetzt?

Ich denke, ich möchte SSL testen, und ich glaube, das wird nicht von Mongrel unterstützt, was ist der beste Entwicklungsserver?

Vielen Dank


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

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

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

Apache vs Nginx

Sie sind beide Webserver. Sie können statische Dateien bereitstellen, aber - mit den richtigen Modulen - auch dynamische Web-Anwendungen bedienen, z. B. solche, die in PHP geschrieben sind. 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 out-of-the-box ausliefern. Dafür müssen Sie Apache / Nginx in Kombination mit einem Add-on verwenden, das später beschrieben wird.

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

Mongrel und andere Produktions-App-Server vs WEBrick

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

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

Mongrel ist jedoch ziemlich altmodisch, heutzutage wird es 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, anders als alles, was ich zuvor erwähnt habe. WEBrick ist komplett in Ruby geschrieben. Mongrel (und die meisten anderen Ruby-Anwendungsserver) ist Teil von Ruby und Teil C (meist Ruby), aber sein HTTP-Parser ist zur Leistungssteigerung in C geschrieben.
  • WEBrick ist langsamer und weniger robust. Es hat einige bekannte Speicherlecks und einige bekannte HTTP-Parsing-Probleme.
  • 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 sich aus irgendeinem Grund für WEBrick als Standardserver entschieden hat. Sie benutzten Thin vorher, also habe ich keine Ahnung, warum sie auf WEBrick umgestiegen sind.

Der App-Server und die Welt

Alle aktuellen Ruby-Anwendungsserver sprechen HTTP, einige App-Server sind jedoch möglicherweise direkt über Port 80 mit dem Internet verbunden, andere nicht.

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

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

  • Einige App-Server können nur eine Anfrage pro Prozess gleichzeitig verarbeiten. Wenn Sie zwei Anfragen gleichzeitig bearbeiten möchten, müssen Sie mehrere App-Server-Instanzen ausführen, von denen jede die gleiche Ruby-App bedient. Diese Gruppe von App-Server-Prozessen wird App-Server-Cluster genannt (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 von Anfragen zwischen den Instanzen im Cluster (Mehr dazu im Abschnitt "I / O-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 annehmen. Sie möchten nicht, dass Ihr App-Server nichts unternimmt, während er darauf wartet, dass der Client die vollständige Anforderung 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, weil sie entweder multithreaded oder evented sind.
  • Die meisten App-Server können statische Dateien bereitstellen, sind aber nicht besonders gut darin. Apache und Nginx können es schneller machen.
  • Normalerweise richten Benutzer Apache / Nginx ein, um statische Dateien direkt zu liefern, aber Anfragen, die nicht mit statischen Dateien übereinstimmen, an den Anwendungsserver weiterzuleiten, ist eine gute Sicherheitsvorkehrung. Apache und Nginx sind sehr ausgereift und können den App-Server vor (möglicherweise böswillig) beschädigten Anfragen schützen.

Warum können einige App-Server direkt mit dem Internet verbunden sein?

  • Phusion Passenger ist ein ganz anderes Biest als alle anderen App-Server. Eine seiner einzigartigen Eigenschaften ist, dass es sich in den Webserver integriert.
  • Der Rainbows-Autor erklärte öffentlich, dass es sicher ist, es direkt dem Internet auszusetzen. Der Autor ist ziemlich sicher, dass es im HTTP-Parser (und ähnlichem) keine Sicherheitslücken gibt. Dennoch gibt der Autor keine Garantie und sagt, dass die Nutzung 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 Biest wie der Rest, dem ich einen eigenen Abschnitt gewidmet habe. Ich habe auch Trinidad und TorqueBox weggelassen, weil ich sie nicht gut genug kenne, aber sie sind nur relevant, wenn Sie JRuby verwenden.

  • Mischling war ziemlich nackt. Wie bereits erwähnt, Mongrel ist rein single-threaded Multi-Prozess, so dass es nur in einem Cluster nützlich ist. Es gibt keine Prozessüberwachung: Wenn ein Prozess im Cluster abstürzt (zB wegen eines Fehlers in der App), muss er manuell neu gestartet werden. Menschen neigen dazu, externe Tools zur Prozessüberwachung wie Monit und God zu verwenden.
  • Unicorn ist eine Gabel von Mongrel. Es unterstützt eine begrenzte Prozessüberwachung: Wenn ein Prozess abstürzt, wird er automatisch vom Master-Prozess neu gestartet. Es kann dafür sorgen, dass alle Prozesse auf einen einzelnen gemeinsamen Socket statt auf einen separaten Socket für jeden Prozess warten. Dies vereinfacht die Reverse-Proxy-Konfiguration. Wie Mongrel ist es rein single-threaded Multi-Prozess.
  • Thin verwendet das Evented-E / A-Modell mithilfe der EventMachine-Bibliothek. Abgesehen von der Verwendung des Mongrel-HTTP-Parsers basiert er in keiner Weise auf Mongrel. Sein Cluster-Modus hat keine Prozessüberwachung, daher müssen Sie Abstürze überwachen. Es gibt keinen Unicorn-ähnlichen Shared-Socket, so dass jeder Prozess auf seinem eigenen Socket wartet. Theoretisch ermöglicht das E / A-Modell von Thin eine hohe Parallelität, aber in den meisten praktischen Situationen, für die Thin verwendet wird, kann ein Thin-Prozess nur eine gleichzeitige Anfrage verarbeiten, sodass Sie immer noch einen Cluster benötigen. Mehr über diese besondere Eigenschaft im Abschnitt "I / O-Parallelitätsmodelle".
  • Puma wurde auch von Mongrel gegabelt, aber im Gegensatz zu Unicorn ist Puma als reines Multithreading konzipiert. Daher gibt es derzeit keine eingebaute Cluster-Unterstützung. Sie müssen besonders darauf achten, dass Sie mehrere Kerne verwenden können (mehr dazu im Abschnitt "Gleichzeitigkeitsmodelle für E / A").
  • Rainbows unterstützt mehrere Parallelitätsmodelle durch die Verwendung verschiedener Bibliotheken.

Phusion Passagier

Phusion Passenger arbeitet sehr unterschiedlich von allen anderen. Phusion Passenger integriert sich direkt in Apache oder Nginx und kann daher mit mod_php für Apache verglichen werden. Genauso wie mod_php es Apache ermöglicht, PHP-Apps auf magische Weise zu bedienen, erlaubt es Phusion Passenger Apache (und auch Nginx!), Ruby-Apps fast magisch zu bedienen. Ziel von Phusion Passenger ist es, alles Just Work (tm) so einfach wie möglich zu machen.

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

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

Die gesamte Konfiguration erfolgt in der Konfigurationsdatei des Webservers. Phusion Passenger automatisiert so ziemlich alles. Es ist nicht erforderlich, einen Cluster zu starten und Prozesse zu verwalten. Prozesse starten / stoppen, neu starten, wenn sie abstürzen usw. - alles automatisiert. Im Vergleich zu anderen App-Servern hat Phusion Passenger weitaus weniger bewegliche Teile. Diese Benutzerfreundlichkeit ist einer der Hauptgründe, warum Menschen Phusion Passenger benutzen.

Im Gegensatz zu anderen App-Servern wird Phusion Passenger hauptsächlich in C ++ geschrieben und ist damit sehr schnell.

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

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

Phusion Passenger im Vergleich zu anderen App-Servern

Phusion Passenger bietet viel mehr Funktionen und bietet viele Vorteile gegenüber anderen App-Servern, wie zum Beispiel:

  • Dynamische Anpassung der Anzahl der Prozesse basierend auf dem Datenverkehr Auf unserem Server mit eingeschränkten Ressourcen, der nicht öffentlich zugänglich ist, führen wir eine Tonne Rails-Apps aus, die in unserer Organisation höchstens einmal täglich verwendet werden. Dinge wie Gitlab, Redmine, etc. Phusion Passenger kann diese Prozesse herunterdrehen, wenn sie nicht verwendet werden, und sie hochdrehen, wenn sie verwendet werden, wodurch mehr Ressourcen für wichtigere Apps zur Verfügung stehen. Mit anderen App-Servern sind alle Ihre Prozesse ständig aktiv.
  • Einige App-Server sind von bestimmten Auslastungen nicht gut genug. Zum Beispiel ist Unicorn nur für schnell laufende Anfragen gedacht: Siehe Unicorn-Website- Abschnitt "Nur in einigen Fällen schlimmer".

Workloads, für die Unicorn nicht gut ist, sind:

  • Streaming-Workloads (zB Rails 4 Live Streaming oder Rails 4 Template Streaming).
  • Workloads, in denen die App HTTP-API-Aufrufe durchführt

Das hybride E / A-Modell in Phusion Passenger Enterprise 4 oder höher macht es zu einer ausgezeichneten 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 Administrationsaufwand erheblich.
  • Automatische Benutzerumschaltung, eine bequeme Sicherheitsfunktion.
  • Phusion Passenger unterstützt viele MRI Ruby, JRuby und Rubinius. Mongrel, Unicorn und Thin unterstützen nur MRI. Puma unterstützt auch alle 3.
  • Phusion Passenger unterstützt mehr als nur Ruby! Es unterstützt auch Python WSGI, so dass es beispielsweise auch Django- und Flask-Apps ausführen kann. In der Tat bewegt sich Phusion Passenger in Richtung eines polyglotten Servers. Node.js unterstützt die Todo-Liste.
  • Out-of-Band-Speicherbereinigung Phusion Passenger kann den Ruby-Garbage Collector außerhalb des normalen Anforderungs- / Antwort-Zyklus ausführen, wodurch die Anforderungszeiten möglicherweise um Hunderte von Millisekunden reduziert 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 willkürliche Arbeit verwendet werden kann. 2) Die Version von Phusion Passenger funktioniert gut mit Multithread-Apps, Unicorns dagegen nicht.
  • Automatisierte Roll-Neustarts Rolling-Neustarts auf Unicorn und anderen Servern erfordern einige Skripterstellung. Phusion Passenger Enterprise automatisiert diesen Weg für Sie vollständig.

Es gibt mehr Funktionen und Vorteile, aber die Liste ist wirklich lang. Für weitere Informationen verweisen wir auf das umfassende Handbuch von Phusion Passenger ( Apache-Version , Nginx-Version ) oder die Website von Phusion Passenger .

E / A-Parallelitätsmodelle

  • Single-Threaded Multi-Prozess. Dies ist traditionell das beliebteste E / A-Modell für Ruby-Anwendungsserver, teilweise weil die Multithreading-Unterstützung im Ruby-Ökosystem sehr schlecht war. Jeder Prozess kann jeweils genau eine Anfrage bearbeiten. Der Webserver lädt Lasten zwischen Prozessen. Dieses Modell ist sehr robust und es gibt wenig Möglichkeiten für den Programmierer, Nebenläufigkeitsfehler einzuführen. Der gleichzeitige Zugriff auf E / A 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 blockierende I / O-Workloads, z. B. für Workloads, bei denen HTTP-APIs aufgerufen werden.
  • Rein multi-threaded. Heutzutage hat das Ruby-Ökosystem eine hervorragende Multithreading-Unterstützung, so dass dieses I / O-Modell sehr brauchbar geworden ist. Multithreading ermöglicht eine hohe E / A-Parallelität und eignet sich daher sowohl für kurz- als auch für lang andauernde blockierende E / A-Workloads. Der Programmierer wird eher Nebenläufigkeitsfehler einführen, aber glücklicherweise sind die meisten Web-Frameworks so entworfen, dass dies immer noch sehr unwahrscheinlich ist. Eine Sache zu beachten ist jedoch, dass der MRI Ruby Interpreter aufgrund der Verwendung der Global Interpreter Lock (GIL) nicht mehrere CPU-Kerne nutzen kann, auch 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, so dass sie mehrere Kerne in einem einzigen Prozess vollständig nutzen können.
  • Hybrid Multi-Threaded Multi-Prozess. Hauptsächlich von Phusion Passenger Enterprise 4 und höher implementiert. Sie können problemlos zwischen Single-Thread-Prozessen mit mehreren Prozessen, reinen Multithread-Prozessen oder sogar mehreren Prozessen mit mehreren Threads wechseln. Dieses Modell gibt das Beste aus beiden Welten.
  • Ausgeglichen. Dieses Modell unterscheidet sich vollständig von dem zuvor genannten Modell. Es ermöglicht sehr hohe E / A-Parallelität und eignet sich daher hervorragend für lang andauernde blockierende E / A-Workloads. Um es zu nutzen, ist eine explizite Unterstützung durch die Anwendung und das Framework erforderlich. Alle wichtigen Frameworks wie Rails und Sinatra unterstützen jedoch keinen "evented code". Aus diesem Grund kann ein Thin-Prozess in der Praxis immer noch nicht mehr als eine Anforderung gleichzeitig verarbeiten, sodass er sich genau so verhält wie das Single-Thread-Multiprozessmodell. Es gibt spezialisierte Frameworks, die die Vorteile von evented I / O nutzen können, beispielsweise Cramp.

Vor Kurzem wurde im Blog von Phusion ein Artikel veröffentlicht, in dem die Anzahl der Prozesse und Threads für Ihre Arbeitslast optimal abgestimmt wird. Siehe Abstimmung 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 Sie in der Regel einige Vorbereitungsarbeiten ausführen, z.

  • Hochladen des Codes und der Dateien der Ruby-App auf den Servercomputer.
  • Bibliotheken installieren, von denen Ihre App abhängig ist
  • Einrichten oder Migrieren der Datenbank
  • Starten und Stoppen aller Daemons, auf die sich Ihre App verlassen könnte, z. B. Sidekiq / Resque-Mitarbeiter oder was auch immer.
  • Irgendwelche anderen Dinge, die getan werden müssen, wenn Sie Ihre Anwendung einrichten.

Im Kontext von Capistrano bezieht sich "Einsatz" auf all diese Vorbereitungsarbeiten. Capistrano ist kein Anwendungsserver. Stattdessen ist es ein Werkzeug zur Automatisierung all dieser Vorbereitungsarbeiten. Sie teilen Capistrano mit, wo sich Ihr Server befindet und welche Befehle bei jeder neuen Version Ihrer App ausgeführt werden müssen. Capistrano kümmert sich dann 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, sie können in Kombination mit Capistrano verwendet werden.

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





mongrel