Schlanke Webserver für Ruby on Rails & Co.: Alternative Diener
Lighttpd – Fettarm läuft schneller
Um sich von den Mühen seines Diploms an der FH Kiel abzulenken, beschäftigte sich Jan Kneschke mit der Optimierung von Programmcode eines minimalen Webservers. Das Ziel war, bis zu 10.000 gleichzeitige Verbindungen zu ermöglichen und die Anfragen ohne Verzögerung zu bearbeiten. Nach nunmehr knapp drei Jahren ist Lighttpd [1] ein leistungsfähiger Webserver geworden, der sich wachsender Beliebtheit erfreut und selbst von Größen wie YouTube und WikiMedia eingesetzt wird. Die Sympathie kommt nicht von ungefähr – die Installation gestaltet sich einfach, selbst die Kompilation aus dem Quellcode gelingt unkompliziert. Im Gegensatz zu Platzhirschen wie Apache ist Lighttpd sehr kompakt und nur von wenigen Voraussetzungen abhängig.
$ ldd /usr/sbin/lighttpd linux-gate.so.1 => (0xffffe000) libpcre.so.3 => /usr/lib/libpcre.so.3 (0xb7ec2000) libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7ebe000) libattr.so.1 => /lib/libattr.so.1 (0xb7eb9000) libssl.so.0.9.8 => /usr/lib/i686/cmov/libssl.so.0.9.8 (0xb7e79000) libcrypto.so.0.9.8 => /usr/lib/i686/cmov/libcrypto.so.0.9.8 (0xb7d37000) libfam.so.0 => /usr/lib/libfam.so.0 (0xb7d2f000) libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7d18000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7bd7000) /lib/ld-linux.so.2 (0xb7eee000) libz.so.1 => /usr/lib/libz.so.1 (0xb7bc2000)
Listing 1
Die Konfiguration von Lighttpd mag für eingefleischte Apache-Administratoren etwas ungewohnt erscheinen. Lighttpd unterstützt das Setzen von Variablen innerhalb der Konfigurationsdatei, selbst mehrdimensionale Felder (Arrays) können verwendet werden. Nach etwas Einarbeitungszeit lernt man die Vorteile jedoch zu schätzen.
var.subdomain = "rails" [...] server.name = var.subdomain + ".t3n.de" index-file.names += ("index.rhtml") [...]
Listing 2
Der Leistungsumfang von Lighttpd ist groß: Virtuelle Server, dynamisches Umschreiben von URLs (ähnlich Apaches mod_rewrite), Kompression mittels zLib, WebDAV, Anbindung an RRDTool und Streaming von Flash-Videos (FLV) stehen neben vielen weiteren Möglichkeiten zur Verfügung.
Im Gegensatz zu anderen Webservern, die für die Unterstützung von Skriptsprachen wie PHP oder Ruby Erweiterungsmodule einbinden, setzt Lighttpd ganz auf die Schnittstellen CGI, FastCGI und SCGI. Die beiden Letzteren sind bedeutend leistungsfähiger als das antike CGI, sie müssen nicht für jede Anfrage einen Prozess der jeweiligen Skriptsprache starten. Stattdessen bleiben ein oder mehrere Prozesse aktiv, um zwischen dem Webserver und der Skriptsprache zu vermitteln.
fastcgi.server = ( ".php" => ( "localhost" => ( "bin-path" => "/usr/bin/php-cgi", "socket" => "/tmp/php.socket" ) ), ".fcgi" => ( "localhost" => ( "bin-path" => "/home/user/www/rails_project/public/dispatch.fcgi", "socket" => "/tmp/rails.socket" ) ) )
Listing 3
Cherokee – Vom anderen Stamm
Ein weiterer Newcomer ist der GPL-lizenzierte Webserver Cherokee [2] des Spaniers Alvaro Lopez Ortega. Cherokee besitzt ein mit Lighttpd vergleichbares Leistungsspektrum. Die Entwicklung wird unter anderem von DynDNS unterstützt, das Unternehmen nutzt den Server für seine Dienste. In einigen Disziplinen ist Cherokee etwas schneller als Lighttpd, kann sich aber momentan nicht mit dem weiter unten vorgestellten Webserver nginx messen. Die Konfiguration ist eng an Apache angelehnt, Umsteiger finden sich schnell zurecht und werden durch eine vollständige und gut verständliche Dokumentation unterstützt.
Mongrel – Rails Deluxe
Die Architektur Mongrels hat der amerikanische Schöpfer und Autor Zed Shaw an den eleganten Java-Webserver Simple [3] angelehnt. Speziell für Ruby-Anwendungen entwickelt ist Mongrel konsequenterweise selbst in Ruby verfasst und kommt daher ohne externe Schnittstellen wie FastCGI oder SCGI aus. Die Funktionalität ist durch GemPlugins [4] erweiterbar, für das Debugging von Rails-Anwendungen stehen umfangreiche Möglichkeiten zur Protokollierung bereit. Als Ergänzung zu einem Rails-Projekt ist Mongrel schnell einsatzbereit:
$ sudo gem install mongrel $ cd rails_project $ mongrel_rails start -d
Listing 4
Das Thread-Modell der aktuellen Ruby-Version skaliert nur begrenzt. Da Mongrel für jede Anfrage einen Thread erzeugt, kann es bei hoher Last zu Leistungseinbrüchen kommen. Darüber hinaus ist Rails nicht vollständig „Thread-Safe“ – Mongrel kann daher Anfragen nur synchron verarbeiten. Möchte man Rails
nicht den Rücken kehren, um seine Webanwendungen zum Beispiel mit dem Thread-freundlicheren Framework Nitro/Og [5] zu entwickeln, bieten sich bei besonders ressourcenlastigen Projekten einige Tuning-Maßnahmen an:
Rails Cache [6] speichert das Ergebnis von Anfragen in einen schnellen Zwischenspeicher, zum Beispiel in einer RAM-Disk. Rails bietet drei verschiedene Arten des Caching („Page“, „Action“, „Fragment“) mit jeweils spezifischen Vor- und Nachteilen. Welcher der Mechanismen für das jeweilige Projekt am besten geeignet ist, sollte sorgfältig geprüft werden. Mit dem „Rails Cache Test Plugin“ [7] lässt sich die eigene Konfiguration für den produktiven Einsatz validieren.
BackgrounDRb [8] ergänzt das Rails-Framework um die Möglichkeit zur verteilten Verarbeitung (Distributed Ruby). Dabei werden die abzuarbeitenden Aufgaben in Threads unterteilt, die asynchron ausgeführt werden – und das wahlweise über die Grenzen des lokalen Systems hinaus. Durch den Einsatz von spezialisierter Hardware skaliert der Verbund optimal. BackgrounDRb arbeitet übrigens auch fern der Schienen mit eigenen Anwendungen.
Mit einem „Pack of Mongrels“ laufen anstelle eines einzelnen Mongrel-Servers mehrere Instanzen gleichzeitig. Im produktiven Betrieb empfehlen sich je nach Anzahl und Leistung der CPUs sechs bis zwölf Mongrels, die jeweils eine andere Portadresse bedienen. Das Plugin „mongrel_cluster“ [9] vereinfacht die Installation eines Mongrel-Clusters erheblich:
$ sudo chown -R mongrel:mongrel /home/user/www/rails_project $ sudo adduser -r mongrel $ sudo gem install -y mongrel_cluster $ sudo mongrel_rails cluster::configure -e production \ -p 8001 -N 6 -c /home/user/www/rails_project -a 127.0.0.1 \ --user mongrel --group mongrel
Listing 5
Die Verteilung auf die drei Mongrels des Clusters kann sowohl in Hardware als auch in Software erfolgen: Switches und Router der Oberliga bieten entsprechende Funktionen und eine Vielzahl von freier Software steht bereit, um einen „Load Balanced Reverse Proxy“ zu betreiben: Pound [10], Lighttpd, ein vorhandener Apache mit „mod_proxy“ oder auch der vielversprechende Newcomer Nginx bieten entsprechende Funktionen.
Nginx – Die russische Maschine
Nginx (gesprochen: engine-x) ist ein unter der BSD-Lizenz verfügbarer Web- und Proxy-Server des russischen Autors Igor Sysoev.
Der Funktionsumfang von Nginx [11] ist vergleichbar mit Lighttpd, verzichtet allerdings auf eine altmodische CGI-Schnittstelle. Die Möglichkeiten zur Konfiguration sind sehr flexibel und entsprechend komplex – Umsteiger können angesichts der noch unvollständigen englischen Dokumentation auf Probleme stoßen. Nach vorläufigen Benchmarks glänzt Nginx durch besonders hohe Leistung und Stabilität. In einigen Tests schlug Nginx selbst Lighttpd, den vermeintlichen „Apache-Killer“, und bewältigte bis zu 35 Prozent mehr Anfragen.
Nginx eignet sich gut als Reverse-Proxy für Lastverteilung und Redundanz. Um unseren zuvor konfigurierten Mongrel-Cluster zu bedienen, sind nur wenige Zeilen zu ergänzen:
[...] upstream mongrel { server 127.0.0.1:8001; server 127.0.0.1:8002; server 127.0.0.1:8003; server 127.0.0.1:8004; server 127.0.0.1:8005; server 127.0.0.1:8006; } [...] location / { [...] proxy_pass http://mongrel; } [...]
Listing 6
Nginx prüft die Verfügbarkeit der einzelnen Server in Intervallen und leitet bei Ausfällen Anfragen nicht mehr an die betroffenen Systeme weiter. Entgegen dem Beispiel in Listing 6 können auch entfernte Systeme eingebunden werden, etwa um während Wartungsarbeiten einen unterbrechungsfreien Betrieb zu gewährleisten.
Fazit
Nachdem es um den Platzhirsch Apache lange Zeit recht ruhig war, zeichnet sich ein lebendiges und spannendes Rennen um den leistungsfähigsten Open-Source-Webserver ab. Auch wenn die neuen, leichtgewichtigen Webserver für viele Einsatzbereiche geeignet sind, besonders im Java-schwangeren Umfeld sind Enterprise-Schwergewichte wie Apache Tomcat zurzeit nicht wegzudenken. Am Horizont erscheint derweil die zweite Generation von AJAX. Comet [12] heißt das neue Zauberwort. Die Technologie verlangt nach geringsten Reaktionszeiten – vielleicht ein weiteres Einsatzgebiet, in dem die vorgestellten schlanken Webserver gegenüber den Boliden Punkten können.