NGINX

TYPO3 mit Komprimierung auf Plesk-Host mit Reverse Proxy nginx

caticonslite_bm_alt

Wird in TYPO3 die Frontend-Komprimierung mit „$GLOBALS[‚TYPO3_CONF_VARS‘][‚FE‘][‚compressionLevel‚] = 9″ und in den TypoScript-Setup-Einstellungen „config.compressJs“ bzw. „config.compressCss“ aktiviert, werden statische „pre-rendered“ JavaScript- und CSS-Dateien im gzip-Format im Ordner „typo3temp/compressor“ abgelegt. Für die korrekte Auslieferung ist für Apache (z.B. in der Datei .htaccess) die folgende Konfiguration erforderlich:

<FilesMatch "\.js\.gzip$">
	AddType "text/javascript" .gzip
</FilesMatch>
<FilesMatch "\.css\.gzip$">
	AddType "text/css" .gzip
</FilesMatch>
AddEncoding gzip .gzip

Seit Plesk 12 wird nginx als Reverse Proxy eingesetzt und statische Dateien werden nicht mehr von Apache, sondern direkt von nginx ausgeliefert. Das führt dazu, dass nginx die Dateien zwar mit dem korrekten „Content-Type“, aber ohne erforderliches „Content-Encoding: gzip“ im HTTP-Header ausliefert und infolgedessen die Dateien vom Browser falsch (so als wären sie nicht komprimiert) interpretiert werden. Analog zur o.g. Konfiguration für Apache ist auch eine Konfiguration für nginx erforderlich: In Plesk kann unter „Einstellungen für Apache & nginx“ der Domain entweder die Option „Intelligente Bearbeitung statischer Dateien“ deaktiviert werden (nicht empfohlen), oder folgende Konfiguration unter „Zusätzliche nginx-Anweisungen“ hinterlegt werden:

location ~ "\.js\.gzip$" {
	add_header Content-Encoding gzip;
	gzip off;
	types { text/javascript gzip; }
}
location ~ "\.css\.gzip$" {
	add_header Content-Encoding gzip;
	gzip off;
	types { text/css gzip; }
}

Diese Konfiguration bringt nginx dazu die komprimierten JS- und CSS-Dateien analog zu Apache zu behandeln und das erforderliche „Content-Encoding: gzip“ im HTTP-Header zu setzen.

NGINX als SSL-Wrapper

caticonslite_bm_alt

NGINX ist bekannt für seine gute Performance und ideal, um als Reverse Proxy bzw. Load Balancer vor speicherintensiven Anwendungsservern (z.B. Apache mit PHP) eingesetzt zu werden und in diesem Zuge auch die HTTPS-Verbindung zu terminieren, damit sich die Anwendungsserver nicht mehr darum kümmern müssen. Um NGINX als SSL-Wrapper einzusetzen ist folgende Konfiguration erforderlich:

server {
        listen 80;
        server_name domain.tld;
 
        return 301 https://domain.tld$request_uri;
}
 
server {
        listen 443;
        server_name domain.tld;
 
        ssl on;
        ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
        ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
        ssl_session_timeout 5m;
        ssl_protocols SSLv3 TLSv1;
        ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
        ssl_prefer_server_ciphers on;
 
        location / {
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_pass http://10.0.0.1/;
        }
}

Die erste server-Anweisung dient dazu alle HTTP-Anfragen auf HTTPS umzuleiten – „domain.tld“ ist selbstverständlich mit der eigenen Domain zu ersetzen. Sollte neben HTTPS auch HTTP möglich sein, ist diese Konfiguration nicht erforderlich und kann weggelassen werden.

Die zweite server-Anweisung behandelt alle HTTPS-Anfragen und leitet diese im sicheren internen Netz auf den Anwendungsserver „10.0.0.1“ via HTTP-Protokoll weiter. Die Zertifikats- und Schlüsseldatei ist, genauso wie die Adresse des Anwendungsservers, an die eigene Infrastruktur anzupassen. Das Ursprungsprotokoll und die Ursprungsadresse werden als X-Forwarded-Proto bzw. X-Forwarded-For HTTP-Header an den Anwendungsserver weitergeleitet und können somit in der Anwendung entsprechend behandelt werden, z.B. um absolute Links für das verwendete Protokoll zu generieren.

In diesem Fall wurde der Einfachheit halber das automatisch erstellte Snakeoil-Zertifikat von Debian verwendet. Die Installation erfolgt mit „apt-get install ssl-cert“, die Verwendung kann im ubuntuusers.de-Wiki nachgelesen werden.

PHP-Serverkonfigurationen im Performancetest

caticonslite_bm_alt

Ziel dieses Vergleichs war es, die performantesten PHP-Konfigurationen für Drupal, TYPO3 und WordPress festzustellen und daraus auf die im Allgemeineinsatz performanteste Konfiguration zu schließen. Getestet wurden die Standardinstallationspakete Drupal 7.16TYPO3 4.7 Government Package und WordPress 3.4.2 mit Apache Bench für einen Zeitraum von je 30 Sekunden (z.B. „ab -kc 250 -t 30 http://127.0.0.1/drupal/“). Um möglichst faire Bedingungen zu schaffen wurden die involvierten Software-Komponenten vor jedem Test neu gestartet (z.B. „/etc/init.d/nginx restart && /etc/init.d/php5-fpm restart“). Der Testinstanz waren vier Kerne eines E5649-Xeon-Prozessors, 16 GB RAM und zwei SATA-Festplatten im Hardware-RAID 1-Verbund exklusiv zugewiesen. Als Software wurden die Komponenten in ihrer Standardkonfiguration aus dem Debian Wheezy-Repository eingesetzt.

Folgende Konfigurationen wurden getestet:

  • apache2-mpm-prefork + libapache2-mod-fcgid
  • apache2-mpm-prefork + libapache2-mod-fcgid + php-apc
  • apache2-mpm-prefork + libapache2-mod-php5
  • apache2-mpm-prefork + libapache2-mod-php5 + php-apc
  • apache2-mpm-prefork + libapache2-mod-suphp
  • apache2-mpm-prefork + libapache2-mod-suphp + php-apc
  • apache2-mpm-worker + libapache2-mod-fcgid
  • apache2-mpm-worker + libapache2-mod-fcgid + php-apc
  • apache2-mpm-worker + libapache2-mod-suphp
  • apache2-mpm-worker + libapache2-mod-suphp + php-apc
  • nginx + php5-fpm
  • nginx + php5-fpm + php-apc

Die performantesten Konfigurationen für Drupal:

  1. 152,94 Requests/s, 250 Concurrency: apache2-mpm-prefork + libapache2-mod-fcgid + php-apc
  2. 147,12 Requests/s, 250 Concurrency: apache2-mpm-worker + libapache2-mod-fcgid + php-apc
  3. 146,68 Requests/s, 100 Concurrency: nginx + php5-fpm + php-apc
  4. 145,83 Requests/s, 50 Concurrency: apache2-mpm-prefork + libapache2-mod-php5 + php-apc
  5. 132,43 Requests/s, 50 Concurrency: apache2-mpm-worker + libapache2-mod-fcgid + php-apc
  6. 130,92 Requests/s, 250 Concurrency: apache2-mpm-prefork + libapache2-mod-php5 + php-apc
  7. 128,88 Requests/s, 50 Concurrency: apache2-mpm-prefork + libapache2-mod-fcgid + php-apc

Die performantesten Konfigurationen für TYPO3:

  1. 180,32 Requests/s, 50 Concurrency: apache2-mpm-prefork + libapache2-mod-php5 + php-apc
  2. 179,99 Requests/s, 250 Concurrency: apache2-mpm-worker + libapache2-mod-fcgid + php-apc
  3. 173,87 Requests/s, 250 Concurrency: apache2-mpm-prefork + libapache2-mod-php5 + php-apc
  4. 166,69 Requests/s, 50 Concurrency: apache2-mpm-worker + libapache2-mod-fcgid + php-apc
  5. 166,03 Requests/s, 250 Concurrency: apache2-mpm-prefork + libapache2-mod-fcgid + php-apc
  6. 163,55 Requests/s, 50 Concurrency: apache2-mpm-prefork + libapache2-mod-fcgid + php-apc
  7. 111,03 Requests/s, 100 Concurrency: nginx + php5-fpm + php-apc

Die performantesten Konfigurationen für WordPress:

  1. 57,75 Requests/s, 100 Concurrency: nginx + php5-fpm + php-apc
  2. 55,97 Requests/s, 250 Concurrency:  apache2-mpm-prefork + libapache2-mod-fcgid + php-apc
  3. 52,21 Requests/s, 50 Concurrency: apache2-mpm-worker + libapache2-mod-fcgid + php-apc
  4. 49,93 Requests/s, 50 Concurrency: apache2-mpm-prefork + libapache2-mod-fcgid + php-apc
  5. 48,99 Requests/s, 250 Concurrency: apache2-mpm-worker + libapache2-mod-fcgid + php-apc
  6. 48,09 Requests/s, 50 Concurrency: apache2-mpm-prefork + libapache2-mod-php5 + php-apc
  7. 46,7 Requests/s, 250 Concurrency: apache2-mpm-prefork + libapache2-mod-php5 + php-apc

Download aller Apache Bench-Ergebnisse und der Excel-Auswertung

Fazit:

Dass libapache2-mod-suphp im Vergleich zu den anderen Testkandidaten nicht gut abschneiden und APC die Performance enorm steigern wird, war bereits vor dem Test klar. Enttäuschend war in jedem Fall die Leistung von WordPress, welche auf fehlende Cachingmechanismen im Core zurückzuführen ist. Im allgemeinen Vergleich zeigte besonders libapache2-mod-fcgid bei hohen (250 Concurrency) und moderaten (50 Concurrency) Zugriffszahlen eine gute Performance. Als reiner Webserver mag nginx zwar schneller als Apache sein, im Zusammenspiel mit PHP konnte sich nginx gegen Apache aber nicht durchsetzen.

Mein (klarer) Favorit ist apache2-mpm-worker + libapache2-mod-fcgid + php-apc, wer einfachere Konfigurationen bevorzugt und bei dem Benutzerrechte keine Rolle spielen ist auch mit apache2-mpm-prefork + libapache2-mod-php5 + php-apc gut bedient.

 nach oben