Am Beispiel von Suse Linux Enterprise Server 10 möchte ich kurz zeigen, wie die Konfiguration eines performanten Webservers mit nginx für statische Inhalte und Apache für dynamische Inhalte aussehen kann.
Vorteil dieser Lösung ist der geringere Footprint von nginx (wie z.B. auch lighty) im Vergleich zu Apache. Statische Dokumente werden schneller augeliefert und benötigen deutlich weniger Hauptspeicher. Bei mehr als 150 gleichzeitgen connections im Produktivbetrieb bleibt bei mir die CPU-Auslastung von nginx sehr gering (<1%). Zudem wird die einfache und bewährte Konfiguration von Apache für die dynamsichen Inhalte genutzt.
Nachteilig ist der erhöhte Administrationsaufwand sowie die Möglichkeit einer zusätzlichen Sicherheitslücke mit nginx.
Sinnvoll ist ebenfalls die Einrichtung von apache als worker (optimal als fgcid, falls php notwendig ist). Im Standard ist überlicherweise prefork konfiguriert, je nach Distribution lässt sich dies umstellen (in einem weiteren Blogeintrag gehe ich auf die Details für SLES ein).
Installation (bezogen aus SLES 10):
Paket nginx-stable-xxx.rpm vom opensuse Repository herunterladen. Nginx (wie auch lighty) sind leider nicht in SLES 10 als Paket vorhanden. Alternativ kann natürlich nginx selbst kompiliert werden.
nginx-Paket installieren mit rpm -ivh nginx-stable-xxx.rpm und alle Abhängigkeiten, falls vorhanden, auflösen.
Da Apache und nginx beide auf Port 80 hören möchten, muss einer der beiden umkonfiguriert werden. In unserem Beispiel Apache. Hierzu gibt es zwei Möglichkeiten:
- Nginx auf Port ip-adresse:80 und Apache auf 127.0.0.1:80 (es wird also Apache gesagt, dass er nur lokal auf 127.0.0.1 horchen soll)
- Nginx auf Port 80 und Apache z.B. auf Port 81. Der Apache Port spielt keine grosse Rolle, er sollte nur nicht belegt sein (herauszufinden über “netstat -an |grep 81″ unter Linux)
Ich habe mich im Beispiel für 2. entschieden.
Dazu muss in der httpd.conf (bei SLES in /etc/apache2/listen.conf) folgende Änderung gemacht werden:
Listen 81
Alle Anfragen, die nginx nicht beantworten kann (z.B. php-Scripts) werden über das Proxy-Modul von nginx an Apache weitergeleitet.
Die Konfiguration von nginx hierzu:
#user nobody;
user wwwrun www;
#worker_processes 1;
worker_processes 2;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
access_log off;
server_tokens off;
location / {
proxy_pass http://127.0.0.1:81;
include /etc/nginx/proxy.conf;
}
location ~* ^.+.(jpe?g|xml|flv|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|js|swf|avi|mp3)$ {
expires 4h;
root /bla/blubb/webroot;
}
}
}
Es wird die Proxy-Konfiguration /etc/nginx/proxy.conf gelesen, die folgendermassen aussieht:
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
Natürlich sollten beide Konfigurationsdateien angepasst werden.
Als Tipp: Mit
if (!-f $request_filename) {
proxy_pass http://127.0.0.1:81;
break;
}
kann z.B. getestet werden, ob eine statische Datei vorhanden ist. Falls nicht, wird an Apache weitergeleitet.
Theoretisch sollte nach der Änderung und einem Restart beider Server alles funktionieren. Wichtig ist, dass beide Server denselben Benutzer für das webroot benutzen (bei SLES wwwroot im Standard), deshalb die Änderung “user wwwrun www;”.
Die Dokumentation der einzelnen nginx-Module kann hier eingesehen werden:
http://wiki.nginx.org/NginxModules
Auf die Umstellung des Apache auf Worker mit fcgid gehe ich in einem weiteren Blogeintrag ein, sonst wird es zu unübersichtlich…