Bessere Performance mit einem Reverse Proxy
In diesem Artikel geht es nicht um PHP, sondern darum, wie man ein PHP-Applikation via Webserver einer großen Besuchermenge zugänglich macht. Der Standard ist aktuell ein Apache (1.3 oder 2.x), der PHP beherrscht (via mod_php oder FastCGI). Darüber kann man dann wunderbar die Webseiten „serven“.
Doch was tut man, wenn durch eine große Besucheranzahl der Webserver droht, in die Knie zu gehen? Der Apache ist sehr vielseitig, reich an Features, stabil und eigentlich nicht wegzudenken. Doch genau diese Vielseitigkeit und der Feature-Reichtum sind ein Nachteil. Er verbraucht außerdem sehr viel Speicher bei hoher Belastung, sprich vielen tausend Verbindungen.
Deshalb stellt man einen Reverse-Proxy vor den Apache-Webserver. Häufig können diese Proxys auch gleich noch die SSL-Verbindung terminieren, Cachen, und mehr oder minder umfangreiches Loadbalancing.
Einige Bereiche einer Webseite benötigen keinen voll ausgestatteten Apache-Boliden, es reicht ein einfacher, kleinerer Webserver. Dazu gehören alle statischen Inhalte, wie Bilder, Javascripte, CSS und statisches HTML.
Außerdem bereiten langsame Clients Probleme bei großen Webseiten. Wenn viele langsame Clients die Apache-Prozesse am Leben halten, weil die Bytes nur langsam durch das Netz tröpfeln, können andere Requests nicht bedient werden. Ein leichtgewichtiger Reverse-Proxy löst dieses Problem.
Sicher ist euch Squid ein Begriff. Squid kann sowohl als Proxy und auch als Reverse Proxy genutzt werden. Squid ist aber so umfangreich und schwer zu konfigurieren, dass er kaum zum Einsatz kommt als Reverse Proxy.
lighty (lighttpd) dürfte auch vielen bekannt vorkommen. Er hat sehr wenig Ressourcenanforderungen an CPU und Speicher, läuft auf High-Traffic-Seiten wie Youtube, Wikipedia, Pirate Bay, Imageshack und weiteren.
Ein weiterer interessanter leichtgewichtiger Webserver ist nginx (gesprochen: engine-x). nginx ist neuer, bietet auch eine großartige Leistung wie Lighty (je nach Einsatzgebiet unterschiedlich, aber auf gleichem Niveau; auf jeden Fall Klassen besser als Apache). Seiten wie WordPress.com, Github, SourceForge und vielen weiteren werden von nginx bereitgestellt. Mehr als 5% aller Webseiten laufen mittlerweile durch einen nginx!
Hier scheiden sich die Geister, welcher von beiden nun besser ist. Wenn man sich mal 1-2 Stunden im Internet umschaut, sind 60% für nginx und 40% schwören auf lighttpd. Das größte Problem des Lighty ist wohl sein Memory-Leak-Problem, jedenfalls liest man das recht häufig von Umsteigern. Deshalb verlassen viele nun das Lager in Richtung nginx.
Im Anhang habe ich auch noch einige Seiten aufgelistet, die sich mit Vergleichen (Features, Performance) beschäftigt haben.
Die größten Vorteile: sehr geringer Speicherverbrauch, der auch nicht wächst bei sehr vielen Verbindungen, da es sich um eine „event-driven architecture“ handelt, anders als der Prozess/Thread-getriebene Apache. Ideal für kleine statische Dateien und als Reverse Proxy.
Mit nginx hat man auch einen Loadbalancer, der RoundRobin, weighted RoundRobin, Heartbeat-Funktionalität(er merkt, wenn ein Backend-Server tot ist) uvm bietet. Er kann selbst Dateien zur Verfügung stellen oder aber an einen/mehrere Apache weitergeben. Man kann ihn auch zum Cachen benutzen, er unterstützt nativ den Memcached.
Hier gibt es auch einen schönen Bericht darüber, wie nginx als IMAP/POP/WEB/SMTP Proxy betrieben werden kann. 10.000 IMAP-Verbindungen, einige davon SSL, und dann nur 10% CPU Last finde ich beeindruckend.
Man kann auch den kompletten Apache abschaffen und PHP unter nginx betreiben, hier eine kleine Anleitung für Debian. Hier ist noch eine sehr schöne Anleitung, die alle Funktionen beleuchtet incl. Konfigurationszeilen. Es gibt viele dutzend Module, mit denen man nginx erweitern kann, dazu einfach das englische nginx-Wiki durchstöbern.
Ich habe selbst noch keinen nginx laufen, da ich keinerlei Webseite im Internet betreibe, wo sich der „Aufwand“ eines Reverse Proxy lohnt. Aber in naher Zukunft werde ich wahrscheinlich mit dem Thema konfrontiert, eine High-Traffic-Seite mit aufbauen zu können. Und da werden wir sicher einen Reverse-Proxy einsetzen.
Falls jemand Erfahrungen im High-Traffic-Bereich hat, möge er gern seine Meinung dazu kundtun, ich würd mich freuen!
—————————————
Es gibt viele Vergleiche zwischen Apache, Lighty und nginx. Hier einige Quellen (googlen geht natürlich auch):
http://www.wikivs.com/wiki/Lighttpd_vs_nginx
http://hostingfu.com/article/nginx-vs-lighttpd-for-a-small-vps
http://royal.pingdom.com/2008/04/17/alternative-web-servers-compared-lighttpd-nginx-litespeed-and-zeus/
http://barry.wordpress.com/2008/04/28/load-balancer-update/ incl. Kommentare
http://www.joeandmotorboat.com/2008/02/28/apache-vs-nginx-web-server-performance-deathmatch/
[…] Dieser Eintrag wurde auf Twitter von Demobereich erwähnt. Demobereich sagte: Unsere Empfehlung: "Bessere Performance mit einem Reverse Proxy" auf PHP Gangsta: https://www.phpgangsta.de/451 #php #nginx #lighttpd #apache […]
Tweets die Bessere Performance mit einem Reverse Proxy | PHP Gangsta - Der PHP Blog erwähnt -- Topsy.com
2 Okt 09 at 08:43
Sehr spannendes Thema. Bis zu dem Punkt an dem dein Artikel endet gehen auch sämtliche anderen mir bekannten „Anleitungen“ im Netz. Was mir fehlt ist ein konkretes How-To zum Nachbauen eines Reverse-Proxy mit nginx oder lighty. Vor allem interessant wäre es für mich in Verbindung mit SSL-Daten.
Bastian
2 Okt 09 at 09:57
Dann schau dir mal oben die Links an. Beispielsweise unter
http://www.linuxjournal.com/article/10108
findest du ein Beispiel dazu.
Dort steht, wie man nginx installiert, eine Basis-Konfiguration, eine Konfiguration zu SSL und eine zu Reverse-Proxying. Auch wie man ein Zertifikat erstellt.
Daraus solltest du dir deine Umgebung sehr einfach zusammenbasteln können, die du haben möchtest. Ich möchte nur ungern das alles kopieren, es ist dort bereits super erklärt.
Michael Kliewe
2 Okt 09 at 10:21
Muss es denn unbedingt ein Apache als Backend sein oder gehen auch andere Webserver (z.B. IIS)? Und kann man auch ein gemischtes Backend haben (z.B. ein Apache und ein IIS)? Sind dann auch noch die Heartbeat-Funktionalitäten verfügbar?
Martin
2 Okt 09 at 16:08
Das macht keinen Unterschied.
Wenn nginx einen Request erhält und Proxy spielen soll, verbindet sich nginx zu einem der Backend-Server, stellt den Request, empfängt das Ergebnis, und sendet das an den Client zurück.
Der Heartbeat ist einfach nur ein Portcheck, soweit ich weiß. Wenn eine Verbindung zu Backend-Server1 nicht möglich ist, wird der einfach übersprungen, solang bis der Port wieder verfügbar ist.
Es ist ein einfacher Heartbeat ob der Server noch verfügbar ist. nginx fragt die Backend-Server nicht nach ihrer Auslastung und verteilt aufgrund dieser Detailinformationen.
Ich habe zuhause unter Ubuntu mal einen nginx installiert und ein wenig experimentiert. Experte bin ich (noch) nicht.
Michael Kliewe
2 Okt 09 at 16:14
Vorab: Hab beruflich mehrere Jahre mit Loadbalancer zu tun gehabt, mit nginx habe ich keine Erfahungen gemacht.
Serverchecks sind im einfachsten Falle Pings oder HEAD-Requests auf den Backendserver. Doch Ideale Konzepte gehen da weiter und beziehen ganz bewusst die Auslastung der Server mit ein. Eine gute Möglichkeit ist es, z.B. per Cronjob ein Script die Auslastung minütlich in eine Textdatei schreiben zu lassen (0-100), die vom Loadbalancer erreichbar ist ist. So kann der Servercheck anhand der Werte die Verteilung der Anfragen steuern.
Würde mit stark wundern wenn nginx solche Checks nicht auch könnte 🙂
Sven
2 Okt 09 at 20:23
Dann finde das doch mal heraus, ich finde nur die 2 Module:
– http://wiki.nginx.org/Nginx3rdPartyModules#EY_Balancer_Module
– http://wiki.nginx.org/Nginx3rdPartyModules#Upstream_Fair_Balancer
Der letzte kann auch Auslastung mit einbeziehen, aber da steht nur was von „e.g. Thin, Ebb, Mongrel“, nichts von Apache/IIS etc.
Michael Kliewe
2 Okt 09 at 21:23
upstream_fair kann Weight-Round-Robin, also einzelnen Backendservern eine Gewichtung geben um besser ausgestatteten Maschinen mehr Last zukommen zu lassen.
http://nginx.localdomain.pl/wiki/UpstreamFair
Der Parameter weight_mode=peak geht ganz grob in die Richtung. Übrigens ist der von mir erwähnte Servercheck im Regelfall unabhängig von der eingesetzten Backend-Technologie. Wie schon gesagt, von Nginx hab ich bisher nur gelesen, jedoch nie ausprobiert.
Sven
3 Okt 09 at 11:33
Wenn du mal nen Stündchen Zeit hast, kannst du es dir ja mal anschauen, und dann aus „Expertensicht“ deine Eindrücke schildern.
Mit welchen Loadbalancern hast du denn sonst gearbeitet? Pound und sowas, oder mehrheitlich Hardware-Loadbalancer?
Michael Kliewe
3 Okt 09 at 12:42
Hauptsächlich habe ich mit den Loadbalancern von KEMP zu tun gehabt.
Jedoch würd ich gern für meinen schwachbrüstigen vServer einen Reverse Proxy vorschalten. Bisher hatte schwebte mir die Lösung mit einem Apachen + mod_proxy vor. Wenn ich die Zeit finde, probiere ich gern auch mal Nginx aus. Das Teil sieht sehr vielversprechend aus. Glaub aber nicht das es in den nächsten Tagen klappt. Muss mich erstmal von einem Urlaub erholen *g*
Sven
3 Okt 09 at 20:02
Also ich nutze auschließlich lighttpd mit fastcgi. Habe auch auf high traffic Seiten bis zu 90-99% idle (XEN HVM virtualisiert mit einem kompletten AMD Opteron 2344HE CPU zugewiesen).
@Sven: wenn deine vServer so „schwachbrüstig“ sind, wieso nutzt du dann Apache? Ich würd es nur einsetzten, wenn du bestimmte module von apache brauchst. Ansonsten ist eher von den resourcen her einfach scheisse 🙂
tjado
4 Okt 09 at 09:57
@tjado:
Weil ich den durch meine tägliche Arbeit am besten behersche 🙂
Achja, hatte auch keinen Grund was anderes kennen zu lernen … bisher *g*
Sven
5 Okt 09 at 10:53
Und dann gab es da noch den Cherokee oder so ähnlich. Ist wohl noch nicht so bekannt und ob der als reverse proxy durchgeht weiss ich auch nicht.
Walter PePeKay
7 Okt 09 at 08:44
Cherokee kann sehr wohl auch als Reverse Proxy dienen. Ich habe es mir aber noch nicht im Detail angeschaut.
Auf der diesjährigen PHPUnconference war Cherokee auch Thema einer Session.
Hat jemand von euch schon Erfahrung damit?
Michael Kliewe
7 Okt 09 at 09:34
Vielen Dank für die Erklärung! Hochinteressanter Artikel!
Monika
20 Nov 09 at 14:22
Kann mich da nur anschließen, viel Danke für den Artikel, echt ein sehr interessante Thema
PS: und auch die Kommentare sind sehr hilfreich 🙂
Voku
10 Jan 10 at 12:38
Hatte letztes Wochenende erst das Vergnügen einen Reverse-Proxy auf zu bauen.
Jedoch habe ich ein leicht abgewandeltes Konstrukt gefahren.
Folgende Dienste lauschen:
Nginx Port 443
Varnish Port 80
Apache Port 8080
Ich lasse mit Nginx die SSL Verbindungen terminieren und als HTTP-Stream an Varnish weiter leiten.
Varnish macht nichts anderes als eine RAM-Disk anzulegen in der er definierte, statische Dateien (Bilder, CSS, JS, etc.) ablegt und damit die User bedient.
Dies reduziert die HDD Zugriffe extrem, da Varnish standardmäßig 1GB Ramdisk nutzt und das reicht eigentlich für die meisten Seiten.
Alle Anfragen dynamischer Natur werden von Varnish an einen Apache Prozess durchgereicht, welche diese abschließend verarbeitet.
Falls ein statischer Content angefragt wird, welcher noch nicht in der Ramdisk liegt, wird diese Anfrage ebenfalls an Apache gesendet und anschließend in der Ramdisk abgelegt.
Damit konnte ich einen deutlichen Leistungsschub bei gleichzeitigem Lastrückgang feststellen.
War zwar ein wenig Bastelei, hat sich jedoch gelohnt.
Mal schauen, vielleicht schreibe ich darüber demnächst mal einen Eintrag…
Dennis
4 Dez 12 at 11:32
@Dennis Danke für die Info! Wenn du bereits Nginx laufen lässt, warum nutzt du dann nicht dessen Cache-Funktionalität? Nginx cacht normalerweise auf der Festplatte, und das ist schon ziemlich schnell. Man kann aber natürlich auch eine Ramdisk nutzen um die letzten Prozentpunkte herauszukitzeln, eine Zeile in der /etc/fstab, und schon nimmt nginx die Ramdisk.
Dann kannst du Varnish weglassen und hast weniger zu konfigurieren und administrieren.
Siehe z.B. hier
http://o-o-s.de/2011-01-21/syscp-nginx-0-8-54-3-mit-ramdisk-cache
Michael Kliewe
4 Dez 12 at 11:39
Hallo,
kann man den Nginx Reverse Proxy Server auf für SSL Offloading verwenden? Man hätte die SSL Zertifikate dann ja nur noch an einem Server und muss diese ja nicht mehr an jedem Webserver austauschen. Oder sehe ich das falsch???
Jan
23 Sep 16 at 11:47
@Jan Ja, das kann man. Steht auch oben im Text „SSL-Verbindung terminieren“.
Bei größeren Umgebungen hat man häufig weniger Reverse-Proxies als Webserver, man reduziert also die Anzahl an Servern, auf denen man die Zertifikate austauschen muss. Korrekt.
Es macht durchaus Sinn das zu tun, nginx als Beispiel kann sehr effizient SSL offloaden.
Man muss nur etwas darauf achten dass der hintere Webserver auch mitbekommt, dass die Seite via HTTPS aufgerufen wurde, denn intern vom Reverse-Proxy zum Webserver wird meistens eine unverschlüsselte Verbindung genutzt. Der Webserver könnte denken dass der Nutzer die Seite unverschlüsselt aufgerufen hat, und deshalb Links, CSS und JS auf den Webseiten dann mit http:// generiert, und das führt zu Mixed Content. Da muss man sich dann z.B. um „X-Forwarded-Proto“ oä. kümmern, oder direkt alles hardcoden auf https://, oder relativ machen (beginnend mit //domain.de/ oder /).
Ein Reverse-Proxy kann einem ordentlich Last von den Webservern abhalten wenn man das Caching gut einstellt. Dabei jedoch auch an eine Cache-Invalidierungs-Strategie denken.
Michael Kliewe
23 Sep 16 at 12:34