Über die Testfahrt hinaus

Alle Welt spricht über die Entwicklung von Webapplikationen mit Ruby on Rails. Doch wie nimmt man eine Rails-Applikation in Betrieb?

Artikel erschienen in Swiss IT Magazine 2006/22

     

Ruby on Rails ist ein Framework für die Entwicklung datenbankbasierter Webanwendungen in Ruby. Mittlerweile sind gut zwei Jahre seit Erscheinen der ersten öffentlichen Rails-Version vergangen, und es hat sich gezeigt, dass Rails kein Spielzeug enthu­siastischer Open-Source-Programmierer ist, sondern sich für die Entwicklung grosser und hoch frequentierter Webanwendungen eignet. Rails hat sich neben Plattformen wie Java EE oder .Net als ernsthafte Alternative für die Webentwicklung etabliert.
Entscheidend für den Erfolg einer Software ist neben ihrer Entwicklung ihre Auslieferung und Inbetriebnahme. Im Falle einer Webanwendung umfasst das Deployment die Installation der Anwendung auf einem oder mehreren Webservern, die Bereitstellung und Migration der benötigten Datenbankserver sowie die Anbindung etwaiger Fremdsysteme.
Die Auslieferung und Inbetriebnahme einer Rails-Anwendung wirft eine Reihe von Fragen auf, wie zum Beispiel welcher und wie viele Webserver verwendet werden sollen oder ob ein einziger Datenbankserver ausreicht.


Die klassische Umgebung

Eine Rails-Produktionsumgebung besteht aus einem oder mehreren Servern, denen jeweils unterschiedliche Rollen zukommen. An vorderster Front steht der Webserver, der die hereinkommenden Requests entgegennimmt und das von der Anwendung erzeugte HTML an den Client liefert. Daneben gibt es den beziehungsweise die Applikationsserver, die die eigentliche Rails-Anwendung als eigenständige Ruby-Prozesse ausführen.
Der dritte Servertyp einer Rails-Installation ist der Datenbankserver. Dieser kann prinzipiell auf derselben Hardware laufen, auf der auch Web- und Applikationsserver ausgeführt werden. In der Praxis hat sich aber aus Gründen der Performance und Ausfallsicherheit der Einsatz eines beziehungsweise mehrerer dedizierter Datenbankserver etabliert.


Von Webrick bis Mongrel

Rails-Anwendungen werden häufig auf Basis des in Ruby programmierten Webservers Webrick entwickelt. Webrick ist Teil der Ruby-Distribution und wird standardmässig für jedes Rails-Projekt verwendet. Er benötigt keine Konfiguration oder andere native Bibliotheken und ist sofort startbar. Durch die leichte Handhabung ist er gerade für die Entwicklung besonders geeignet. Da er jedoch sehr langsam, speicherhungrig und fehlerbehaftet ist, eignet er sich nicht für die Produktion.




Demzufolge wurde für die ersten produktiven Rails-Projekte der weitverbreitete und stabile Webserver Apache in Kombination mit FastCGI eingesetzt. FastCGI übernimmt in diesem Szenario die Rolle des Applikationsservers und kann entweder auf derselben Maschine wie Apache oder auf dedizierter Hardware betrieben werden. FastCGI zeichnet sich gegenüber CGI durch eine deutlich bessere Performance aus, da jeder FastCGI-Prozess nur einmal gestartet wird und nach Beendigung des Request sofort für den nächsten Request zur Verfügung steht.





Ein weiterer produktionstauglicher Webserver neben Apache ist der schlanke und schnelle Lighttpd. Lighttpd arbeitet genau wie Apache zusammen mit FastCGI, zeichnet sich aber durch eine deutlich höhere Geschwindigkeit und einfachere Konfiguration aus. Gerade letzteres dürfte wohl viele Entwickler zum Umstieg von Apache auf Lighttpd bewegt haben. Dies gilt auch für Cherokee, der bereits in der vorletzten Ausgabe von InfoWeek vorgestellt wurde.




Eine Alternative zu Apache beziehungsweise Lighttpd in Kombination mit FastCGI stellt die Verwendung des HTTP-Servers Mongrel dar, der speziell für das Betreiben von Webanwendungen in Ruby entwickelt wurde. Apache arbeitet hierbei als Proxy und kommuniziert mit Mongrel über HTTP. Da Mongrel in Ruby geschrieben und damit als Ruby-Prozess ausgeführt wird, kann die eigentliche Rails-Anwendung in diesem Szenario direkt von Mongrel betrieben werden, so dass der Einsatz von FastCGI entfallen kann. Apache in Kombination mit Mongrel kann ohne Umschweife für den Produktivbetrieb von Rails-Anwendungen empfohlen werden.


Mein SQL, dein SQL...

Bezüglich der Datenbank gibt es für Rails keine besonderen Anforderungen. Die Liste der unterstützten Datenbanken wächst ständig und besteht derzeit unter anderem aus MySQL, PostgresSQL, SQLite, DB2, Oracle und dem Microsoft SQL-Server. Die Anbindung weiterer, bisher noch nicht unterstützter Datenbanken ist durch die Entwicklung eines eigenen Adapters einfach möglich.
Was die Anzahl der Datenbankserver angeht, ist den Autoren dieses Artikels keine Rails-Anwendung bekannt, die aus Performance-Gründen mehr als einen Datenbankserver benötigt. Anders hingehen sieht es in bezug auf Ausfallsicherheit aus. Hier empfiehlt sich der Einsatz eines weiteren Datenbankservers, der im Falle eines Ausfalls die Arbeit übernimmt.


Abfahrt

Sind alle Plattformfragen geklärt und die benötigte Hardware beschafft und installiert, muss die Anwendung deployed werden. Deployment besteht aus einer Vielzahl von Einzelschritten: Auschecken der Software aus dem Versionskontrollsystem, Kopieren der Software auf den beziehungsweise die Produktionsserver, Aktualisierung und Migration der Datenbankschemata und einigen weiteren Aufgaben.
Mit Capistrano steht Rails-Entwicklern ein ausgereiftes Werkzeug für das automatisierte Deploy­ment von Rails-Anwendungen zur Verfügung. Einmal konfiguriert, lässt sich die Anwendung von jedem Entwicklungsrechner aus auf Knopfdruck und ohne weiteres menschliches Zutun deployen. Deployment als fehleranfällige und zeitaufwändige Disziplin gehört damit der Vergangenheit an.


Last abfedern

Die Zahl potentieller Benutzer einer öffentlich zugänglichen Webanwendung ist nur schwer vorhersehbar. Steigende Benutzerzahlen erzeugen zunehmende Last, auf die das System vorbereitet sein sollte.
Zentraler Mechanismus für gute Performance ist Caching, bei dem dynamische Seiten nach ihrer Erzeugung zwischengespeichert und bei Folge-Requests direkt aus dem Cache geliefert werden. Rails-Caching ist für Produktionsumgebungen standardmässig aktiviert und steht in drei Varianten zur Verfügung: Seiten-Caching, Action-Caching und Fragment-Caching. Jede dieser Varianten hat ihre Vor- und Nachteile und muss entsprechend der jeweiligen Bedürfnisse konfiguriert werden.
Der nächste Schritt in Richtung Performance-Steigerung sollte die Hardware-technische Trennung von Web-, Applikations- und Datenbankserver sein, sofern dies nicht schon Teil des Standard-Setups war.
Stellt sich heraus, dass die Anwendung trotz konfiguriertem Caching und Hardwaretrennung der Servertypen nicht performant genug reagiert, besteht die nächste Ausbaustufe in der horizontalen Skalierung der Anwendung. Dabei werden einfach zusätzliche Applikationsserver ins System genommen, die sich die Bearbeitung der eingehenden Requests unterein­ander aufteilen. Voraussetzung dafür, dass dies funktioniert, ist, dass während der Entwicklung
des Systems die Share-Nothing-Regel eingehalten wird. Hierbei handelt es sich um ein spezielles Architektur-Muster, welches besagt, dass die Anwendung keine Request-überdauernden Daten in der Web- oder Anwendungsschicht speichert.


Schutz vor Entgleisung

Ausfallsicherheit ist eine zentrale Anforderung für unternehmenskritische Anwendungen. Selbst wenn die Anwendung auf nur einem Server performant genug betrieben werden kann, ist dieser eine Server nicht ausreichend, wenn eine hohe Verfügbarkeit gewährleistet werden muss.
Ist dies der Fall, dann muss die Ausfallsicherheit für alle drei Servertypen hergestellt werden, das heisst Web-, Applikations- und Datenbankserver müssen gedoppelt werden. Auch hier ist die Einhaltung der Share-Nothing-Regel obligatorisch.


Alles genau im Auge

Das Monitoring dient dazu, jederzeit den aktuellen Status der Anwendung zu erfahren. Während das Aufsetzen einer Rails-Produktionsumgebung sowie das Deployment der Anwendung bereits auf eine Reihe etablierter Lösungen zurückgreifen können, ist es für die Überwachung häufig noch erforderlich, auf eigene Lösungen zurückzugreifen beziehungsweise diese bei anderen abzugucken.
Eine Rails-Anwendung schreibt in Produktion ihre Logausgaben in die Datei production.log. Zusätzlich stehen die Logdateien des verwendeten HTTP-Servers zur Verfügung. Manuelles Durchsuchen der Logdateien sollte durch Hintergrundprozesse automatisiert sein, die die Logdateien parsen und beim Erkennen entsprechender Fehler eine E-Mail an den verantwortlichen Administrator senden. Alternativ lässt sich das verwendete Logging-System so konfigurieren, dass schwerwiegende Fehler neben einem Dateieintrag eine
E-Mail mit Detailinformationen erstellen und versenden.


Beispielkonfiguration bellybutton.de

Bellybutton (www.bellybutton.de) wird derzeit von den Autoren dieses Beitrags weiterentwickelt und basiert auf einem typischen Rails-Setup: Eingehende Requests werden von einem einzigen Apache-Webserver entgegengenommen und per Loadbalancer auf zwei Applikationsserver verteilt. Auf den Applikationsservern laufen jeweils fünf Mongrel-Prozesse, die die eigentliche Rails-Applikation ausführen. Im Hintergrund arbeiten zwei MySQL-Datenbankserver, wobei der Primärserver sämtliche Anfragen bearbeitet und der Sekundärserver nur im Fehlerfall zum Einsatz kommt. Damit dies funktioniert, treten die beiden MySQL-Server nach aussen als Cluster auf und werden während des Betriebs kontinuierlich repliziert. Fällt der Primärserver aus, schaltet MySQL automatisch um. Die Rails-Anwendung muss dafür weder speziell vorbereitet noch gesondert konfiguriert werden.


Die Autoren

Ralf Wirdemann und Thomas Baustert ( info@b-simple.de) sind freiberufliche Software-Entwickler und Coaches aus Hamburg. Sie sind Autoren des Buches «Rapid Web Develop-ment mit Ruby on Rails».




Artikel kommentieren
Kommentare werden vor der Freischaltung durch die Redaktion geprüft.

Anti-Spam-Frage: Wieviele Zwerge traf Schneewittchen im Wald?
GOLD SPONSOREN
SPONSOREN & PARTNER