Nginx: Webserver klein und schnell
Der schlanke Webserver Nginx aus russischer Produktion gewinnt ständig Marktanteile gegenüber Apache. Dieser Artikel gibt eine Einführung in seine Konfiguration.
Wenn es um Webserver geht, fällt den meisten Administratoren als erstes Apache ein, der in der globalen Statistik des Web auch an erster Stelle steht. Kleinere und schnellere Alternativen gewinnen jedoch immer mehr Anhänger, so zum Beispiel Lighttpd und Cherokee. Als zusätzlicher Wettbewerber stieg vor einiger Zeit der Nginx-Server (ausgesprochen englisch "Engine-ex") in den Ring [1]. Er steht für hohe Performance, Stabilität, umfangreiche Features, einfache Konfiguration und geringen Ressourcenverbrauch. Das Resultat der Bemühungen des Programmierers Igor Sysoev verrichtet seinen Dienst in vielen großen Sites, zum Beispiel Wordpress.com, Hulu und Linuxquestions.org. Ungewöhnlich: Außer als Webserver kann Nginx auch als Proxy für die Mail-Protokolle IMAP und POP3 auftreten.

Abbildung 1: Wie die grüne Linie rechts unten zeigt, gewinnt Nginx immer mehr Anhänger. (Quelle: Netcraft)
In der Domäne HTTP kann Nginx die folgenden Fähigkeiten vorweisen: Statische Dateien ausliefern, Reverse Proxying mit optionalem Caching, fehlertolerantes Load Balancing, remote FastCGI mit Caching/Beschleunigung und SSL/TLS Server Name Indication (SNI), was die Notwendigkeit einer eigenen IP-Adresse zur SSL-Konfiguration für jeden virtuellen Server überflüssig macht. Wie Apache ist Nginx modular aufgebaut und bietet einiges an Funktionalität über Module an, die der Administrator aktivieren oder deaktivieren kann. Anders als der prozessbasierte Apache verarbeitet Nginx alle Anfragen asynchron skaliert dadurch wesentlich besser. Apache verwendet für neue Anfragen einen neuen Prozess oder Thread, was zu einem höheren Verbrauh an Ressourcen wie Speicher führt.
Installation
Wenn Sie nur eine einfache Site betreiben oder gerade ein Projekt neu starten, können Sie möglicherweise auch komplett auf Apache verzichten. Am besten werfen Sie einen Blick auf die Module-Seite von Nginx [2] und prüfen, ob die Module alle ihre Ansprüche befriedigen. Dieser Artikel beschreibt im weiteren einen typischen Aufbau, in dem Nginx als lastausgleichender Revery Proxy vor mehreren Apache-Backends arbeitet. Nginx liefert einen Teil der statischen Inhalte aus und komprimiert selbstätig die dynamischen Seiten, die vom Apache kommen.
Die meisten Linux-Distributionen führen Nginx-Pakete in ihren Repositories, sodass sich der Server leicht über den Paketmanager installieren lässt. Wenn das Paket zu alt ist oder ganz fehlt, finden Sie den Quellcode auf der Nginx-Homepage. Die Installation läuft über die typischen Configure- und Make-Aufrufe. Obwohl die Defaults in den meisten Fällen wohl in Ordnung sind, sollten Sie einen Blick auf die Konfiguration werfen und sie gegebenenfalls anpassen. Die Ausgabe von Configure sieht typischerweise etwa so aus:
Configuration summary + using system PCRE library + using system OpenSSL library + md5: using OpenSSL library + using sha1 library: /usr/include + using system zlib library
Sie sollten sicherstellen, dass die geforderten Bibliotheken auch installiert sind, wenn Sie die entsprechende Funktionalität nutzen möchten. So erfordert Rewrite beispielsweise die PCRE-Library, und SSL setzt die OpenSSL-Bibliothek voraus.
Einstellungssache
In diesem Artikel gehen wir von einer Infrastruktur bestehend aus drei Servern aus. Der Computer mit Nginx befindet sich im Internet vor den beiden Rechnern, die dahinter im privaten Netz stehen. Sie haben deshalb auch keine IP-Adresse im Internet. Tabelle 1 fasst die Konfiguration zusammen.
| Tabelle 1: Layout | ||
|---|---|---|
| Rechner | Front-End-IP | Back-End-IP |
| nginx | 10.0.0.1 | 192.168.1.1 |
| web01 | none | 192.168.1.2 |
| web02 | none | 192.168.1.3 |
Die dazugehörige Konfigurationsdatei »nginx.conf« sieht aus wie in Listing 1.
| Listing 1: »nginx.conf« |
|---|
01 user nobody;
02 worker_processes 2;
03
04 events {
05 worker_connections 1024;
06 use epoll;
07 }
08
09 http {
10 include mime.types;
11 default_type application/octet-stream;
12 log_format custom '$http_host $remote_addr - $remote_user [$time_local] "$request" '
13 '$status $body_bytes_sent "$http_referer" '
14 '"$http_user_agent"';
15 access_log /path/to/access.log custom;
16 sendfile on;
17 server_tokens off;
18
19 upstream cluster {
20 server 192.168.1.2 weight=1; // the weight can be adjust to send more
21 server 192.168.1.3 weight=1; // traffic to specific machine(s).
22 }
23
24 server {
25 listen 10.0.0.1:80;
26 server_name www.domain.com domain.com;
27 location / {
28 proxy_pass http://cluster;
29 proxy_redirect off;
30 proxy_set_header Host $host;
31 proxy_set_header X-Real-IP $remote_addr;
32 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
33 proxy_buffers 8 32k;
34 }
35 }
36 } |
Diese Konfiguration führt zu dem Ergebnis, dass beide Backend-Server ungefähr gleich viele Zugriffe abbekommen. Per Default führt Nginx ein einfaches Load Balancing nach der Round-Robin-Methode durch, das heißt, bei jeder Anfrage einfach der nächste Backend-Server dran. Um eine Verteilung basierend auf der IP-Adresse des anfragenden Clients zu realisieren, bietet Nginx die Konfigurationsdirektive »ip_hash«. Ausgefeiltere Load-Balancing-Methoden sind für zukünftige Nginx-Versionen geplant.
Ohne weiteres Zutun kommen die Requests bei den Backend-Server alle mit der IP-Adresse des Nginx-Frontends an. Am besten übergeben Sie die IP-Adresse der ursprünglichen Anfrage mit dem HTTP-Header »X-Forwarded-For« und verarbeiten sie in den Apache-Prozessen mit dem Module »mod_rpaf« weiter. Es schreibt die Remote-Adresse wieder um, sodass andere Apache-Module die gewünschte Information erhalten. Das freie Modul finden Sie auf der Website [3].
SSL-Sicher
Nginx als SSL-Proxy zu verwenden bringt mehrere Vorteile. Die Apache-Konfiguration vereinfacht sich, die CPU-Belastung durch SSL-Verschlüsselung wird verringert und das Load Balancing wird einfacher, da man sich nicht um SSL-Sessions kümmern muss. SSL mit Nginx einzurichten ist einfach und setzt die gleichen CRT- und KEY-Dateien voraus wie sonst Apache. Die zusätzlichen Einstellungen zeigt Listing 2.
| Listing 2: SSL-Konfiguration |
|---|
01 server {
02 listen 10.0.0.1:443;
03 server_name www.domain.com;
04 add_header Front-End-Https on;
05 keepalive_timeout 70;
06 ssl on;
07 ssl_certificate /path/to/server.crt;
08 ssl_certificate_key /path/to/server.key;
09
10 location / {
11 proxy_pass http://cluster;
12 proxy_redirect off;
13 proxy_set_header Host $host;
14 proxy_set_header X-Real-IP $remote_addr;
15 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
16 proxy_buffers 4 32k;
17 proxy_set_header X-Forwarded-Proto https;
18 }
19 }
20 } |
Allerdings gibt es zwei Einschränkungen beim Nginx-SSL-Support. Die Stable-Version beherrscht keine Revocation Lists, mit denen sich Zertifikate ungültig machen lassen. In der Entwicklerversion ist diese Funktion aber bereits unterstützt. Außerdem lassen sich Chain-Zertifikate nicht wie bei Apache in extra Dateien verwalten. Stattdessen muss der Administrator die Daten des Chain-Zertifikats an das Hauptzertifikat anhängen, zum Beispiel mit »cat chain.crt >> server.crt«. Danach muss er sich nicht weiter um das Chain-Zertifikat kümmern, sondern kann wie gehabt mit dem im Konfigurationspunkt »ssl_certificate« angegebenen Zertifikat arbeiten.
Statisch
Im nächsten Schritt soll Nginx lernen, statische Dateien, nämlich Bilder auszuliefern. Damit können Sie die Backend-Server für dynamische Seiten optimieren. Die Ablaufzeit für das Caching der Bilder soll auf 30 Tage einstellt werden, sodass wiederkehrende Clients die Bilder nur beim ersten Mal übers Netz laden müssen. Der folgende Abschnitt in der Konfigurationsdatei realisiert diese Anforderungen:
location ~* ^.+\.(jpg|jpeg|gif|png)$ {
root /path/to/www;
expires 30d;
}Wer das Logging für ausgelieferte Bilder komplett abschalten möchte, erreich das mit der folgenden Zeile:
access_log off;
Die Komprimierung von Textinhalten per Gzip kann etwas Bandbreite bei der Auslieferung sparen, wovon vor allem Anwender mit einer langsamen Leitung profitieren. Allerdings belastet sie den Prozessor des Servers etwas mehr. Der Abschnitt in Listing 3 legt fest, dass Nginx nur bestimmte Mime-Typen komprimiert und die Komprimierung für den Internet Explorer komplett abschaltet, weil es damit bekanntliche Probleme gibt.
| Listing 3: Gzip-Komprimierung |
|---|
01 gzip on; 02 gzip_http_version 1.0; 03 gzip_vary on; 04 gzip_min_length 1100; 05 gzip_buffers 16 8k; 06 gzip_comp_level 5; 07 gzip_proxied any; 08 gzip_types text/plain text/css application/javascript text/javascript text/xml application/x-javascript; 09 gzip_disable "MSIE [1-6]\."; |
Um die Verarbeitung der Client-Anfragen noch weiter zu beschleunigen, gibt es zwei Möglichkeiten zum Caching von Inhalten: dateibasiert oder mit Memcache. Aufpassen muss man allerdings generell, wenn man Inhalte cachen will, die sich unterscheiden, je nachdem ob er User eingeloggt ist oder nicht. Den dateibasierten Cache schaltet die folgende Zeile ein:
proxy_cache_path /data/nginx/cache \ levels=1:2 keys_zone=one:10m;
Der Parameter level legt die Anzahl von Unterverzeichnissen für den Cache fest. Nginx verwendet als Key und Dateiname einen MD5-Hash der URL, sodass Dateinamen aussehen wie »/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c«. Wenn der Cache-Pfad im HTTP-Kontext der Konfiguration eingerichtet ist, können Sie den Cache selber im HTTP-, Server- oder Location-Abschnitt einstellen. Um alle Antworten mit den HTTP-Codes 200 und 300 für eine halbe Stunde zu cachen und alle 404-Antworten für 5 Minuten, verwenden Sie beispielsweise diese Einstellungen:
proxy_cache one; proxy_cache_valid 200 302 30m; proxy_cache_valid 404 5m;
Mit Memcache zu cachen geht beinahe genauso einfach, wie Listing 4 zeigt.
| Listing 4: Memcache-Einstellungen |
|---|
01 server {
02 location / {
03 set $memcached_key $uri;
04 memcached_pass name:11211;
05 default_type text/html;
06 error_page 404 @fallback;
07 }
08
09 location @fallback {
10 proxy_pass cluster;
11 }
12 } |
Statistik
Viele verbreitete Monitoring-Lösungen verarbeiten die Ausgabe des Apache-Moduls »httpd mod_status«. Bei Nginx übernimmt das Modul »stub_status« eine ähnliche Rolle. Defaultmäßig fehlt es, deshalb müssen Sie es im Configure-Schritt mit »--with-http_stub_status_module« aktivieren. Haben Sie es installiert, richten Sie es mit den Einstellungen aus Listing 5 ein.
| Listing 5: Modul »stub_status« |
|---|
01 location /nginx_status {
02 stub_status on;
03 access_log off;
04 allow TRUSTED.IP.ADDRESSES
05 deny all;
06 } |
Eine HTTP-Anfrage auf »http://Server/nginx_status« führt damit zu einer Antwort wie in Listing 6.
| Listing 6: Status-Meldung |
|---|
01 Active connections: 291 02 server accepts handled requests 03 16630948 16630948 31070465 04 Reading: 6 Writing: 179 Waiting: 106 05 This server has 291 active connections, has accepted and handled 16630948 connections while serving 31070465 requests... |
Zusatz
Kaum eine Apache-Site kommt ohne Mod-Rewrite aus, zum Beispiel um die ,,hässlichen URLs`` mit Query-Parameter in URLs mit gut lesbaren Pfaden umzuwandeln. Nginx hat zwar auch ein Rewrite-Modul, aber sein Syntax unterscheidet sich vom Apache-Pendant. Die ganze Wahrheit darüber verrät das Nginx-Wiki [5]. Der folgende Konfigurationscode schreibt die URLs wie beschrieben suchmaschinen- und anwenderfreundlich um:
rewrite ^/users/(.*)$ /user.php?user=$1?\ last;
Eine etwas aufwändigere Variante führt eine If-Abfrage ein, um die Websitebesucher immer zur gleichen Domain weiterzuleiten:
if ($host ~* www\.(.*)) {
set $host_without_www $1;
rewrite ^(.*)$ \
http://$host_without_www$1 permanent;
}Für Geotargeting, also die Anpassung der ausgelieferten Webseite an den Standort des Users, gibt es ein GeoIP-Modul. Es erzeugt Variablen basierend auf der IP-Adresse des Anwenders und beruht auf den Maxmind-GeoIP-Datenbanken. Das Nginx-Modul setzt zwei Dinge voraus: die LibGeoIP und eine Maxmind-Datenbank. Die neueste LibGeoIP findet sich wie die Datenbank auf der Maxmind-Site [6], sie ist aber auch schon in vielen Distributions-Repositories enthalten. Diese beiden Zeilen, im HTTP-Kontext der Konfiguration eingesetzt, schalten das GeoIP-Modul ein:
geoip_country GeoIP.dat; geoip_city GeoLiteCity.dat;
Damit stehen in Nginx die unter [7] gelisteten Variablen zur Verfügung. Häufig verwenden Webanwendungen mit Nginx beispielsweise »$geoip_country_code«, um die Requests an verschiedene Upstream-Server, je nach Land, weiter zu leiten. Um die GeoIP-Infos auch an die Backends weiterzuleiten, verwenden Sie diese Anweisung:
proxy_set_header HTTP_GEO $geo;
Tabelle 2 führt noch weiter Nginx-Module auf und erklärt kurz, wofür sie zuständig sind.
| Tabelle 2: Nginx-Module | |
|---|---|
| Modul | Funktion |
| HTTP Referer | Filtert Requests basierend auf dem Referer. |
| HTTP Limit Zone | Beschränkt die gleichzeitige Zahl von Verbindungen pro Client |
| HTTP Limit Requests | Beschränkt die Zugriffshäufigkeit pro Client |
| User ID | Liefert Cookies aus, die den User identifizieren |
| HTTP Addition | Hängt beliebigen Text an ausgelieferte Seiten an. |
| FLV | Flash Video-Streams |
| Perl | Macht Perl-Code und Serverside-Includes direkt mit Nginx ausführbar |
| WebDAV | Verarbeitet WebDAV-Anfragen durch |
| Substitution | Textersetzung in Webseiten |
| Image Filter | Bildverarbeitung mit dem GD-Modul |
| Secure Link | Schützt Seiten mit einem Schlüssel vor unbefugtem Zugriff |
| XSLT | Verarbeitet Seiten mit XSL weiter |
Fazit
Nginx als Caching Reverse Proxy für eine existierende Webserver-Installation mit Apache einzusetzen, kann die Gesamtperformance eines Webauftritts deutlich steigern. Am besten sehen Sie sich die Online-Dokumentation sehr genau an und testen Nginx gründlich, bevor Sie den Server produktiv einsetzen. (ofr)
Infos
- [1] Nginx: [http://www.nginx.org]
- [2] Nginx-Module: [http://wiki.nginx.org/NginxModules]
- [3] Mod_rpaf: [http://stderr.net/apache/rpaf/]
- [4] Tim Schürmann, Verteiltes Caching mit Memcached, Linux-Magazin Sonderheft 02/2009, S. 58
- [5] Nginx-Rewrite-Modul: [http://wiki.nginx.org/NginxHttpRewriteModule]
- [7] GeoIP-Variablen: [http://wiki.nginx.org/NginxHttpGeoIPModule]
Der Autor
Jeremy Garcia ist Gründer und Administrator der Website Linuxquestions.org, die Nginx als Reverse Proxy für ihre Inhalte einsetzt und eine der größten Online-Communities zu Linux betreibt. Er benutzt Linux seit mehr als 10 Jahren und ist ein leidenschaftlicher, wenn auch realistischer Open-Source-Anhänger.

Kommentare
Kommentar hinzufügen