“gzip” für Webseiten

Um das Verhalten von “gzip / deflate” besser zu verstehen, möchte ich als erstes ganz kurz auf den Algorithmus hinter der Komprimierung eingehen. Dafür muss man zumindest zwei Grundlegende Theorien verstehen. Zum einen die sogenannte Huffman-Kodierung, dabei geht darum Text mit möglichst wenig Bits (0 || 1) zu übersetzen.

Es folgt ein einfaches Beispiel:

String: “im westen nichts neues”

Die Länge des Strings beträgt 22 Zeichen, was bei einem 4-Bit-Code (0000, 0001 …) eine Anzahl von 22 * 4 Bit = 88 Bit ergeben würde.

Berücksichtigt man jedoch die Häufigkeit der wiederkehrenden Zeichen, kann man für bestimmte Zeichen, welche oft im String vorkommen, kürzere Bit-Codes nutzen.

huff1

Als erstes Zählen wir die Anzahl der vorkommenden Zeichen. Die Zeichen welche die geringste Häufigkeit aufweisen werden anschließend als erstes miteinander Verknüpft und jeweils addiert.

huff4

Wie man bereits erkennt bekommen die Zeichen welche nicht so häufig auftreten längere Strecken und somit gleich auch längere Bit-Codes.

huff7

Wenn man alle Zweige verknüpft hat, entsteht daraus dann ein Binär-Baum, welcher von oben nach unten gelesen wird.

Die eindeutigen Bit-Codes sind nun z.B.: 00 für e, 100 für n, 1011 für t und so weiter. Nun benötigen wir nur noch 73 Bit anstatt 88 Bit, um den String binär darzustellen. ;)

Das zweite Prinzip hat auch mit Wiederholung von Zeichen zu tun. Die sogenannte “LZ77″ Kompression, welche wiederkehrende Muster in Strings erkennt und durch Referenzen von vorherigen Strings ersetzt.

Es Folgt ein einfaches Beispiel:

String: “Blah blah blah blah blah!”

 vvvvv     vvvvv     vvv
Blah blah blah blah blah!
      ^^^^^     ^^^^^

Wenn man nun die Wiederholung durch eine Referenz angibt, welche aus der Länge des Wortes (” blah” = 5) und Länge der Wiederholungen. (“lah blah blah blah” = 18). Daraus ergibt sich anschließend der folgende komprimierte Text.

Blah b(5,18)!

… aber nun endlich zum praktischen Teil! Es folgen ein paar Beispiele und Überlegungen im Zusammenhang mit Webseiten / Webservern.

1.) “gzip”, ABER weniger ist manchmal mehr

Bei kleinen Webseiten und schwachen V-Servern kann es vorkommen, dass die serverseitige Komprimierung im Gesamtkontext keinen Geschwindigkeitsvorteil bietet, da die Komprimierung ggf. mehr Overhead (Payload, CPU-Rechenzeit, Verzögerung der Auslieferung) mit sich bringt als es Vorteile (geringere Dateigröße) bietet. Zumal viele Dateien (Bilder, CSS, JS) nach dem ersten Seitenaufruf im Cache sind und nicht wieder vom Server ausgeliefert werden müssen. Gerade für mobile Geräte macht die Komprimierung jedoch fast immer Sinn, daher würde ich die Komprimierung immer aktivieren!

PS: hier noch ein Blog-Post zum Thema Webseiten Beschleunigen

moelleken_org-gzip
mit gzip
moelleken_org-nogzip
ohne gzip

GRÜN = Download
GELB = Wartet
BLAU = Verbindung zum / vom Server

Bei “nginx” gibt es zudem ein Modul (HttpGzipStaticModule) welches direkt vorkomprimierte Dateien ausliefert, anstatt diese bei Anfrage zu komprimieren. Jedoch muss man bisher selber dafür sorgen, dass eine entsprechende Datei mit dem selben Timestamp vorhanden ist. (z.B.: main.css & main.css.gz) Falls jemand hier eine Alternative oder ein einfaches Script zum erstellen der zu komprimierenden Dateien hat, meldet euch bitte bei mir oder einfach in den Kommentaren.

2.) “gzip”, ABER nicht für alles

Zunächst sollte man bereits komprimierte Dateien (z.B. JPEG, PNG, zip etc.) nicht noch zusätzlich via „gzip“ ausliefern, da die Dateigröße im schlimmsten Fall noch steigen kann oder zumindest wird für sehr wenig Dateigröße, sehr viel CPU-Zeit auf der Server (Komprimierung) und auf dem Client (Dekomprimierung) verbraucht.

gzip_images

Ich empfehle an dieser Stelle mal wieder die “.htaccess“-Datei vom HTML5-Boilerplate, welche bereits viele Einstellungen für den Apache-Webserver liefert. Außerdem gibt es dort auch eine optimierte Konfiguration “nginx.conf” für den nginx-Webserver.

3.) “gzip”, ABER nicht immer

Die “gzip”-Komprimierung kann Ihre Stärken bei größeren Dateien viel besser ausspielen, da wir ja bereits im theoretischen Teil gelernt haben, dass die Komprimierung auf Wiederholungen aufbaut und wenn wenig wiederkehrende Zeichen und Muster vorhanden sind lässt es sich schlecht komprimieren.

Beim “nginx”-Webserver kann man die minimale zu bearbeitende Dateigröße angeben, sodass eine 6 Byte große Datei mit dem Inhalt “foobar” bei schwacher „gzip“ nicht auf 40 Byte vergrößert wird.

gzip_small_file

4.) “gzip”, ABER nicht so hoch

Zudem sollte man nicht mit der höchsten Komprimierungsstufe komprimieren, da man pro Komprimierungsstufe immer weniger Erfolg bei immer mehr CPU-Zeit bekommt. Man sollte weniger stark komprimieren und dadurch Rechenleistung /-zeit einsparen, um die Webseite schneller ausliefern zu können.

gzip_level

test2_1.js.gz (schwache Komprimierung)
test2_2.js.gz (normale Komprimierung)
test2_3.js.gz (starke Komprimierung)

5.) „gzip“ + Minifizierung

Durch Minifizierung von CSS und JS kann man die Dateigröße ebenfalls reduzieren, auch wenn man nicht an die Dateigröße von komprimierten Dateien herankommt, außerdem sinkt der Erfolg der Komprimierung, da wir durch die Minifizierung bereits einige Wiederholungen minimiert haben.

Es folgt ein Beispiel mit „jquery.js / jquery.min.js“:

Zustand

Größe der Datei

gewonnene Größe durch die Komprimierung

nicht minifiziert + nicht komprimiert Datei

250 kB (¼ MB)

nicht minifiziert + schnelle Komprimierung

76,3 kB

173,7 kB

nicht minifiziert + normale Komprimierung

68,3 kB

181,7 kB

nicht minifiziert + hohe Komprimierung

68 kB

182 kB

minifiziert + nicht komprimiert Datei

82,3 kB

minifiziert + schnelle Komprimierung

30,8 kB

51,5 kB

6.) “gzip” + Komprimierung verbessern

Im Gegensatz zur Programmierung, wo man Wiederholungen vermeidet, sollte man im Frontend (HTML, CSS) gezielt Wiederholungen nutzen, um die Komprimierung zu optimieren. So zeigt  das folgende Beispiel wie man die Dateigröße durch die korrekte Positionierung von Attributen der HTML-Tags verbessern kann.

Zwei Dateien mit dem selben Dateigröße, nur die Reihenfolge der Attribute in der zweiten HTML-Dateien (“test1_2.html”) wurden nicht in der selben Reihenfolge angegeben.

html_order_3
test1_1.html
html_order_2
test1_2.html

html_order

Wie man in dem Bild erkennen kann, haben wir die Dateigröße der HTML-Datei um zirka 10% reduziert indem wir den Komprimierungsalgorithmus  bei der Arbeit unterstützen. ;)

Videos:

 

nginx + google-pagespeed

ngx_pagespeed

Google hat “pagespeed” für nginx veröffentliche, die nginx Äquivalent vom “mod_pagespeed” für Apache. Dieses Modul kann die Performance von Webseiten optimieren, indem z.B. die zugehörigen Assets (CSS, JavaScript, Bilder) verkleiner bzw. kombiniert werden, um die Ladezeiten zu reduzieren. Dieses Tutorial erklärt wie nginx + pagespeed auf Debian kompiliert/installiert werden kann.

 

Bevor wie starten können müssen wir ggf. einige Pakete nachinstallieren und “deb-src” in der “/etc/apt/sources.list” einfügen / auskommentieren.

apt-get update
apt-get install dpkg-dev build-essential zlib1g-dev libpcre3 libpcre3-dev
cd /usr/src/
apt-get source nginx
apt-get build-dep nginx
cd nginx-*/debian/modules/
git clone https://github.com/pagespeed/ngx_pagespeed.git
cd ngx_pagespeed
wget https://dl.google.com/dl/page-speed/psol/1.7.30.1.tar.gz
tar -xzvf 1.7.30.1.tar.gz
cd /usr/src/nginx-*/
vim debian/rules

# und folgende Zeile in der config (config.status.full: config.env.full config.sub config.guess) hinzufügen …

--add-module=$(MODULESDIR)/ngx_pagespeed \

# anschließend können wir uns ein neues “*.dep”-Paket bauen

dpkg-buildpackage -b
dpkg --install ../nginx-full*.dep

# … check …

nginx -V

z.B.:

root@h1687374> nginx -V
nginx version: nginx/1.5.10
TLS SNI support enabled
configure arguments: –prefix=/etc/nginx –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-client-body-temp-path=/var/lib/nginx/body –http-fastcgi-temp-path=/var/lib/nginx/fastcgi –http-log-path=/var/log/nginx/access.log –http-proxy-temp-path=/var/lib/nginx/proxy –http-scgi-temp-path=/var/lib/nginx/scgi –http-uwsgi-temp-path=/var/lib/nginx/uwsgi –lock-path=/var/lock/nginx.lock –pid-path=/var/run/nginx.pid –with-pcre-jit –with-debug –with-http_addition_module –with-http_auth_request_module –with-http_dav_module –with-http_geoip_module –with-http_gzip_static_module –with-http_image_filter_module –with-http_realip_module –with-http_stub_status_module –with-http_ssl_module –with-http_sub_module –with-http_xslt_module –with-http_spdy_module –with-ipv6 –with-mail –with-mail_ssl_module –with-openssl=/usr/src/nginx-1.5.10/debian/openssl-1.0.1f –add-module=/usr/src/nginx-1.5.10/debian/modules/nginx-auth-pam –add-module=/usr/src/nginx-1.5.10/debian/modules/nginx-echo –add-module=/usr/src/nginx-1.5.10/debian/modules/nginx-upstream-fair –add-module=/usr/src/nginx-1.5.10/debian/modules/nginx-dav-ext-module –add-module=/usr/src/nginx-1.5.10/debian/modules/nginx-cache-purge –add-module=/usr/src/nginx-1.5.10/debian/modules/ngx_pagespeed

vim /etc/nginx/nginx.conf

# … und folgende Zeilen über den vHosts einfügen …

pagespeed on;
pagespeed FileCachePath /var/ngx_pagespeed_cache;
mkdir /var/ngx_pagespeed_cache
chown -R www-data:www-data /var/ngx_pagespeed_cache
/etc/init.d/nginx restart
curl -I -p http://localhost | grep X-Page-Speed
apt-get install memcached

# aktiviere memcache  

vim /etc/default/memcached
/etc/init.d/memcached restart

# optional: Fehleranalyse

tail -f /var/log/nginx/error.log  

 

Beispiel-Seite:

http://moelleken.org

 

Beispiel-Konfig:

https://github.com/voku/CONFIG–nginx—php-fpm—mysql

 

Download: (alternativ kann man auch meine bereis kompilierte Version testen)

http://suckup.de/downloads/nginx-full_1.5.10_i386.deb

http://suckup.de/downloads/nginx-common_1.5.10_all.deb

http://suckup.de/downloads/nginx-1.5.10_all.deb

 

Links:

Google-Pagespeed-Doku: https://developers.google.com/speed/pagespeed/module/config_filters

Google_Pagespeed-HowTo: https://developers.google.com/speed/pagespeed/module/build_ngx_pagespeed_from_source

Filter-Übersicht: http://ngxpagespeed.com/ngx_pagespeed_example/

Rewrite-Rules: Apache vs Nginx

Bei dem Apache Webserver wird das URL-Handling (Rewrite-Rules) via .htaccess gesteuert, sobald sich eine Datei mit diesem Namen in einem Verzeichnis befindet, werden die darin enthaltenen Befehle vom Apache umgesetzt. Da dieses Verfahren jedoch voraussetzt, dass alle Verzeichnisse zuvor auf eine solche Datei geprüft, diese anschließend eingelesen und verarbeitet werden muss, macht es Sinn wie z.B. beim Nginx Webserver diese in die Konfiguration des Webs aufzunehmen. Leider ist die Syntax und Logik dieser beiden Rewrite-Rules nicht kompatibel, daher folgt eine Einführung in dieses Thema … außerdem habe ich auf github.com/voku/ meine kompletten Konfigurationsdaten für Nginx + PHP + MySQL hochgeladen.

 

Erklärung: einfache Weiterleitung

 

Apa­che:

Redirect /altes_Verzeichnis/alte_Seite.html http://suckup.de/

 

Nginx: 

rewrite /altes_Verzeichnis/alte_Seite.html http://suckup.de/ last;

 

Falls “/altes_Verzeichnis/alte_Seite.html” hinter deiner Domain in der URL steht, wird die Anfrage auf die Domain “meine_domain.de” umgeleitet.

z.B. http://suckup.de/altes_Verzeichnis/alte_Seite.html

 

Erklärung: Domain Weiterleitung

 

Apa­che:

RewriteCond %{HTTP_HOST} ^voku-online.de$ [NC]
RewriteRule ^(.*)$ http://www.suckup.de/$1 [R=301,L]

 

%{HTTP_HOST} -> Hostname

 

Nginx: 

if ($host ~* voku-online.de) {
rewrite ^(.*)$ http://suckup.de$1 permanent;
}

 

Fall der Hostname “voku-online.de” ist, dann wird dieser zu “suckup.de” umgeschrieben und alles was hinter der ursprünglichen Hostnamen stand, wird hinter den neuen gesetzt. 

^ -> Anfang 

.* -> “.” ein beliebiges Zeichen, “*” Wiederholung => alle beliebigen Zeichen

( ) -> erstes Vorkommen der einfachen Klammern wird zur ersten Variable $1 … u.s.w.

$ -> Ende

z.B. http://voku-online.de/altes_Verzeichnis/alte_Seite.html

 

Erklärung: entferne doppelte “/”

 

Apa­che:

RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]

 

 %{REQUEST_URI} -> URL ohne Parameter

 ( ) -> erstes Vorkommen der einfachen Klammern in der “RewriteCond”-Bedingung wird zur ersten Variable %1 … u.s.w.

 

Nginx: 
if ($request_uri ~* “\/\/”) {
rewrite ^(.*)$ $scheme://$host$1 permanent;
}

 

\/ -> Escapezeichen “\” vor “/”

$scheme -> http bzw. https

$host -> Hostname

permanent -> gibt den Statuscode 301 zurück

 

Erklärung: statische Dateien (.css/.js/.html) beschleunigen

 

Nginx:

## static files are served directly
location ~* \.(?:js|css|htm?|js\?ver.*|css\?ver.*)$ {
        set $betterForCache  0;

        if ($args ~* ver=(.*)$) {
                set $betterForCache  1;
        }
        if ($request_uri ~* “/wp-admin”) {
                set $betterForCache  0;
        }
        if ($betterForCache = 1) {
                rewrite ^(.*) $scheme://$host$uri? last;
        }

        gzip_static on;

        autoindex off;
        expires 1d;
        add_header Pragma public;
        # We bypass all delays in the post-check and pre-check parameters of Cache-Control. Both set to 0.
        add_header Pragma public;
        add_header Cache-Control “public, must-revalidate, proxy-revalidate, post-check=0, pre-check=0”;
        ## No need to bleed constant updates. Send the all shebang in one
        ## fell swoop.
        tcp_nodelay off;
        ## Set the OS file cache.
        open_file_cache max=3000 inactive=120s;
        open_file_cache_valid 45s;
        open_file_cache_min_uses 2;
        open_file_cache_errors off;
        break;
}

Verschachtelte if-Abfragen kann man einfach via Hilfsvariablen (z.B. $betterForCache) erstellen …

$uri -> URL ohne Parameter

z.B.: http://suckup.de/wp-content/themes/mystique/css/core.css?ver=3.3.2

 

weitere Infos:

– Nginx & HttpRewriteModule:  http://wiki.nginx.org/HttpRewriteModule

– Apache & mod_rewrite: http://httpd.apache.org/docs/current/mod/mod_rewrite.html

– Beispiel-Konfiguration (WordPress Multi: Nginx + PHP-FPM): https://github.com/voku/CONFIG–nginx—php-fpm—mysql

Nginx + Varnish auf Debian/Ubuntu

Zurück zur “Webseiten beschleunigen” – Übersicht

5.4) Nginx mit Varnish


“Varnish ist ein Web-Beschleuniger für dynamische Web-Seiten mit viel Inhalt. Im Gegensatz zu anderen Web-Beschleunigern, die häufig aus clientseitigen Proxies oder aus Servern entstanden, wurde Varnish von Grund auf als Web-Beschleuniger konzipiert.” – Wiki


Als erstes erweitern wir unsere sources.list, so dass wir die Varnish-Software einfach installieren / updaten können:


Ubuntu:

echo "http://repo.varnish-cache.org/ubuntu/ lucid varnish-2.1" >> /etc/apt/sources.list


Debian:

echo "deb http://repo.varnish-cache.org/debian/ lenny varnish-2.1" >> /etc/apt/sources.list


Nun installieren wir Varnish…

curl http://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add -
aptitude install varnish


Nun müssen wir einige Eistellungen an Varnish vornehmen, so dass dieser als erstes angesprochen wird…

vim /etc/default/varnish
# Configuration file for varnish
#
# /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK
# to be set from this shell script fragment.
#

# Should we start varnishd at boot?  Set to "yes" to enable.
START=yes

# Maximum number of open files (for ulimit -n)
NFILES=131072

# Maximum locked memory size (for ulimit -l)
# Used for locking the shared memory log in memory.  If you increase log size,
# you need to increase this number as well
MEMLOCK=82000

# Default varnish instance name is the local nodename.  Can be overridden with
# the -n switch, to have more instances on a single server.
INSTANCE=$(uname -n)

## Configuration with VCL
#
DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"

## TEST
#
#DAEMON_OPTS="-a :80 \
#             -T localhost:6082 \
#             -f /etc/varnish/default.vcl \
#             -s malloc,512M \
#             -p lru_interval=3600 \
#             -p thread_pool_max=2000 \
#             -p listen_depth=2048 \
#             -p 'cc_command=exec cc -fpic -shared -Wl,-x -L/usr/include/libmemcached/memcached.h -lmemcached -o %o %s' \
#             -h classic,500009 \
#             -t 0"

## Alternative 3, Advanced configuration
#
# See varnishd(1) for more information.
#
# # Main configuration file. You probably want to change it :)
# VARNISH_VCL_CONF=/etc/varnish/default.vcl
#
# # Default address and port to bind to
# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify
# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets.
# VARNISH_LISTEN_ADDRESS=
# VARNISH_LISTEN_PORT=6081

#
# # Telnet admin interface listen address and port
# VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
# VARNISH_ADMIN_LISTEN_PORT=6082
#
# # The minimum number of worker threads to start
# VARNISH_MIN_THREADS=1
#
# # The Maximum number of worker threads to start
# VARNISH_MAX_THREADS=1000
#
# # Idle timeout for worker threads
# VARNISH_THREAD_TIMEOUT=120
#
# # Cache file location
# VARNISH_STORAGE_FILE=/var/lib/varnish/$INSTANCE/varnish_storage.bin
#
# # Cache file size: in bytes, optionally using k / M / G / T suffix,
# # or in percentage of available disk space using the % suffix.
# VARNISH_STORAGE_SIZE=1G
#
# # File containing administration secret
# VARNISH_SECRET_FILE=/etc/varnish/secret
#
# # Backend storage specification
# VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"
#
# # Default TTL used when the backend does not specify one
# VARNISH_TTL=120
#
# # DAEMON_OPTS is used by the init script.  If you add or remove options, make
# # sure you update this section, too.
# DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
#              -f ${VARNISH_VCL_CONF} \
#              -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
#              -t ${VARNISH_TTL} \
#              -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \
#              -S ${VARNISH_SECRET_FILE} \
#              -s ${VARNISH_STORAGE}"
#


Nun muss du die Konfig anpassen, ich zeige hier ein Beispiel für meinen WordPress Blog… ggf. musst du für deine Webseiten jedoch noch weitere Einstellungen ändern.


vim /etc/varnish/default.vcl
backend default {
        .host = "127.0.0.1";
        .port = "8080";
}

acl purge {
        "localhost";
}

sub vcl_fetch {
        set beresp.ttl = 12h;
        set req.grace = 24h;
        if (req.url ~ "wp-(login|admin)") {
                return (pass);
        }
        if (req.url ~ "feed") {
                return (pass);
        }
        return (deliver);
        unset beresp.http.set-cookie;
        if (req.url ~ "\.(jpeg|jpg|png|gif|ico|swf|js|css|txt|gz|zip|rar|bz2|tgz|tbz|html|htm|pdf|pls|torrent)$") {
                set beresp.ttl = 48h;
        }

        remove req.http.X-Forwarded-For;
        set    req.http.X-Forwarded-For = req.http.rlnclientipaddr;
        if (req.url ~ "^/w00tw00t") {
                error 403 "Not permitted";
        }
        return(deliver);
}

sub vcl_deliver {
        if (obj.hits > 0) {
                set resp.http.X-Cache = "HIT";
                set resp.http.X-Cache-Hits = obj.hits;
        } else {
                set resp.http.X-Cache = "MISS";
        }
        remove resp.http.X-Varnish;
        remove resp.http.Via;
        remove resp.http.Age;
        remove resp.http.X-Powered-By;
}

sub vcl_recv {
        set req.grace = 6h;
        if (req.request == "PURGE") {
                if(!client.ip ~ purge) {
                        error 405 "Not allowed.";
                }
                purge("req.url ~ ^" req.url "$ && req.http.host == "req.http.host);
        }
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|lzma|tbz)(\?.*|)$") {
                remove req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
                set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
                set req.http.Accept-Encoding = "deflate";
        } else {
                remove req.http.Accept-Encoding;
        }
        if( req.url ~ "^/wp-(login|admin)" || req.http.Cookie ~ "wordpress_logged_in_" ) {
                return (pass);
        }
        if (!(req.url ~ "wp-(login|admin)")) {
                unset req.http.cookie;
        }
        if (req.request != "GET" &&
                req.request != "HEAD" &&
                req.request != "PUT" &&
                req.request != "POST" &&
                req.request != "TRACE" &&
                req.request != "OPTIONS" &&
                req.request != "DELETE") {
                return (pipe);
        }
        if (req.request != "GET" && req.request != "HEAD") {
                return (pass);
        }
        if (req.http.Authorization || req.http.Cookie) {
                return (pass);
        }
        if (req.url ~ "\.(jpeg|jpg|png|gif|ico|swf|js|css|txt|gz|zip|rar|bz2|tgz|tbz|html|htm|pdf|pls|torrent)(\?.*|)$") {
                unset req.http.Authenticate;
                unset req.http.POSTDATA;
                set req.request = "GET";
                set req.url = regsub(req.url, "\?.*$", "");
                return (lookup);
        }
        unset req.http.cookie;
        return (lookup);
}

sub vcl_pipe {
        set bereq.http.connection = "close";
        if (req.http.X-Forwarded-For) {
                set bereq.http.X-Forwarded-For = req.http.X-Forwarded-For;
        } else {
                set bereq.http.X-Forwarded-For = regsub(client.ip, ":.*", "");
        }
}

sub vcl_pass {
        set bereq.http.connection = "close";
        if (req.http.X-Forwarded-For) {
                set bereq.http.X-Forwarded-For = req.http.X-Forwarded-For;
        } else {
                set bereq.http.X-Forwarded-For = regsub(client.ip, ":.*", "");
        }
}


Parallel müssen wir nun unseren Webserver, egal ob Apache oder in diesem Fall Nginx, auf den Port 8080 lauschen lassen.  Beim Nginx ist dies relativ simpel, du muss nur “listen 80” -> “listen 8080” ändern. Ich zeige an dieser Stelle jedoch einmal meine Nginx-Konfiguration für meinen WordPress Blog.

[stextbox id=”warning”]Wie immer gilt, erst verstehen, dann kopieren… :-)[/stextbox]

server {
        listen 8080;
        server_name suckup.de www.suckup.de blog.voku-online.de linux.voku-online.de windows.voku-online.de ubuntu.voku-online.de allgemein.voku-online.de cdn1.voku-online.de cdn2.voku-online.de cdn3.voku-online.de cdn4.voku-online.de cdn5.voku-online.de *.suckup.de;
        root /var/www/www.suckup.de/web/;
        index index.php;
        access_log /var/log/nginx/suckup.access.log main;
        error_log /var/log/nginx/suckup.error.log;
        log_not_found on;

        ## Cache - testen
        open_file_cache max=2500 inactive=24h;
        open_file_cache_valid    24h;
        open_file_cache_min_uses 2;
        open_file_cache_errors   on;

        location ~* ^.+.(htm|html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)(\?[0-9]+)?$ {
                root /var/www/www.suckup.de/web/;
                access_log off;
                expires max;
                break;
        }

        ## Optimierung - "(css/js).php" to "(css/js)"
        location /wp-content/plugins/wp-special-textboxes/css/ {
                location ~* \.(css.php)$ {
                        if ($args ~* ver=(.*)$) {
                                rewrite ^ $scheme://$host/wp-content/cache/wp-special-textboxes.css? permanent;
                        }
                }
        }
        location /wp-content/plugins/wp-special-textboxes/js/ {
                location ~* \.(js.php)$ {
                        if ($args ~* ver=(.*)$) {
                                rewrite ^ $scheme://$host/wp-content/cache/wstb.js? permanent;
                        }
                }
        }
        if ($args ~* ver=3.0.1$) {
                rewrite ^ $scheme://$host/wp-content/cache/wp-special-textboxes.css? permanent;
        }

        if (-f $request_filename) {
                break;
        }
        if (!-e $request_filename) {
                rewrite ^(.+)$ /index.php?q=$1 last;
        }

        # -----------------------------------------
        # http://wiki.nginx.org/Wordpress

        ## remove any multislashes //
        if ($request_uri ~* "\/\/") {
                rewrite ^/(.*) $scheme://$host/$1 permanent;
        }

        ## Slash am Ende anfuegen ?!?
        #if ($request_uri ~* "^[\w\-\/]+[^\/?]$") {
                #rewrite ^(.*)$ $scheme://$host$1/ permanent;
        #}

        ## www eifuegen
        #if ($host !~* ^(www|subdomain)) {
                #rewrite ^/(.*)$ $scheme://www.$host/$1 permanent;
        #}

        ## www vorne entfernen
        if ($host ~* ^www\.(.*)) {
                set $host_without_www $1;
                rewrite ^(.*)$ http://$host_without_www$1 permanent;
        }

        ## immer SSL verwenden
        #rewrite ^(.*) https://$server_name$1 permanent;

        ## immer HTTP verwenden
        #rewrite ^(.*) http://$server_name$1 permanent;

        ## Feedburner
        rewrite ^/e107_plugins/rss_menu/rss.php?(.*)$ http://suckup.de/feed/ last;
        if ($http_user_agent !~ (FeedBurner|Googlebot)) {
                rewrite ^/feed/?$ http://feeds.feedburner.com/suckup last;
                break;
        }

        ## WordPress3
        #if (!-e $request_filename) {
                #rewrite ^(.+)$ /index.php?q=$1 last;
                #break;
        #}

        ## WordPress3 MU
        #if (!-e $request_filename) {
                #rewrite ^.+/?(/wp-.*) $1 last;
                #rewrite ^.+/?(/.*\.php)$ $1 last;
                #rewrite ^(.+)$ /index.php?q=$1 last;
                #break;
        #}

        ## WordPress3 Multi-Domain
        rewrite ^.*/files/(.*)$ /wp-includes/ms-files.php?file=$1 last;
        if (!-e $request_filename) {
                rewrite ^.+/?(/ms-.*) $1 last;
                rewrite ^/files/(.+) /wp-includes/ms-files.php?file=$1 last;
                rewrite ^.+/?(/wp-.*) $1 last;
                rewrite ^.+/?(/.*.php)$ $1 last;
                rewrite ^(.+)$ /index.php?q=$1 last;
                break;
        }
        location ~* ^.+.(htm|html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)(\?[0-9]+)?$ {
                access_log off;
                expires max;
                root /var/www/www.suckup.de/web/;
                rewrite ^/.(/wp-.*/.*.(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))(\?[0-9]+)?$ $1 last;
                break;
                rewrite ^.*/files/(.*(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))(\?[0-9]+)?$ /wp-includes/ms-files.php?file=$1 last;
                break;
                if (!-e $request_filename) {
                        rewrite ^.+/?(/wp-.*) $1 last;
                        rewrite ^.+/?(/.*.php)$ $1 last;
                        rewrite ^(.+)$ /index.php?q=$1 last;
                        break;
                }
        }

        ## WordPress-Forum
        if (!-e $request_filename) {
                rewrite ^/forums/topic/(.*)$ /forums/topic.php?q=$1 last;
                rewrite ^/forums/forum/(.*)$ /forums/forum.php?q=$1 last;
                rewrite ^/forums/profile/(.*)$ /forums/profile.php?q=$1 last;
                rewrite ^/forums/view/(.*)$ /forums/view.php?q=$1 last;
                rewrite ^/forums/tags/(.*)$ /forums/tags.php?q=$1 last;
                rewrite ^/forums/rss/(.*)$ /forums/rss.php?q=$1 last;
                rewrite ^/forums/bb-admin/ /forums/bb-admin/index.php last;
                rewrite ^/forums/ /forums/index.php last;
                break;
        }

        ## WordPress W3 Total Cache
        set $totalcache_file '';
        set $totalcache_uri $request_uri;
        if ($request_method = POST) {
                set $totalcache_uri '';
        }
        if ($query_string) {
                set $totalcache_uri '';
        }
        if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
                set $totalcache_uri '';
        }
        if ($totalcache_uri ~ ^(.+)$) {
                set $totalcache_file /wp-content/w3tc-suckup.de/pgcache/$1/_default_.html.gzip;
        }
        if (-f $document_root$totalcache_file) {
                rewrite ^(.*)$ $totalcache_file break;
        }

        ## WordPress SuperCache
        #set $supercache_file '';
        #set $supercache_uri $request_uri;
        #if ($request_method = POST) {
                #set $supercache_uri '';
        #}
        #if ($query_string) {
                #set $supercache_uri '';
        #}
        #if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
                #set $supercache_uri '';
        #}
        #if ($supercache_uri ~ ^(.+)$) {
                #set $supercache_file /wp-content/cache/supercache/$http_host/$1index.html;
        #}
        #if (-f $document_root$supercache_file) {
                #rewrite ^(.*)$ $supercache_file break;
        #}

        #if (!-e $request_filename) {
                #rewrite . /index.php last;
        #}

        # -----------------------------------------

        ## memchached test
        #location / {
                #default_type text/html;
                #add_header "Content" "text/html; charset=utf8";
                #charset utf-8;
                #set $memcached_key $uri;
                #memcached_pass 127.0.0.1:11211;
                #error_page 500 404 405 = @fallback;
        #}
        #location @fallback {
                #try_files $uri $uri/ @suckup;
        #}

        location / {
                try_files $uri $uri/ @suckup;
                sub_filter suckup.de:8080
                'suckup.de:80';
                sub_filter_once on;
        }

        location @suckup {
                include /etc/nginx/fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root/index.php;
                fastcgi_param QUERY_STRING q=$uri&$args;
                fastcgi_param SCRIPT_NAME /index.php;
                fastcgi_pass 127.0.0.1:11000;
        }

        location ~ \.php$ {
                try_files $uri @suckup;
                ## memchached test
                #set $memcached_key $uri;
                #memcached_pass  127.0.0.1:11211;
                fastcgi_index index.php;
                fastcgi_pass 127.0.0.1:11000;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /etc/nginx/fastcgi_params;
        }

        ## .htaccess & .htpassword sperren
        location ~ /\.ht {
                deny  all;
        }
}

Nginx + WordPress

Ich habe bereits in einem vorherigem Blog-Post erklärt, wie du “Nginx” (Webserver) unter Debian und / oder Ubuntu installierst. Heute zeige ich mit einigen Beispielen, wie du Nginx konfigurierst, diese Einstellungen werden in dem entsprechendem “Virtual Host” (/etc/nginx/sites-enabled/*.conf) durchgeführt.

## Slash am Ende anfuegen
if ($request_uri ~* "^[\w\-\/]+[^\/?]$") {
    rewrite ^(.*)$ $scheme://$host$1/ permanent;
}
## entferne doppel-slashes //
if ($request_uri ~* "\/\/") {
    rewrite ^/(.*) $scheme://$host/$1 permanent;
}
## www eifuegen
if ($host !~* ^(www|subdomain)) {
    rewrite ^/(.*)$ $scheme://www.$host/$1 permanent;
}
## www vorne entfernen
if ($host ~* ^www\.(.*)) {
    set $host_without_www $1;
    rewrite ^(.*)$ http://$host_without_www$1 permanent;
}
## immer SSL verwenden
    rewrite ^(.*) https://$server_name$1 permanent;
## immer HTTP verwenden
    rewrite ^(.*) http://$server_name$1 permanent;
## WordPress3
if (!-e $request_filename) {
    rewrite ^(.+)$ /index.php?q=$1 last;
    break;
}
## WordPress3 MU
if (!-e $request_filename) {
    rewrite ^.+/?(/wp-.*) $1 last;
    rewrite ^.+/?(/.*\.php)$ $1 last;
    rewrite ^(.+)$ /index.php?q=$1 last;
    break;
}
## WordPress3 Multi-Domain
rewrite ^.*/files/(.*)$ /wp-includes/ms-files.php?file=$1 last;
if (!-e $request_filename) {
    rewrite ^.+/?(/ms-.*) $1 last;
    rewrite ^/files/(.+) /wp-includes/ms-files.php?file=$1 last;
    rewrite ^.+/?(/wp-.*) $1 last;
    rewrite ^.+/?(/.*.php)$ $1 last;
    rewrite ^(.+)$ /index.php?q=$1 last;
    break;
}
location ~* ^.+.(htm|html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
    access_log off;
    expires max;
    root /var/www/www.domain.de/web/;
    rewrite ^/.(/wp-.*/.*.(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))$ $1 last;
    rewrite ^.*/files/(.*(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))$ /wp-includes/ms-files.php?file=$1 last;
    if (!-e $request_filename) {
        rewrite ^.+/?(/wp-.*) $1 last;
        rewrite ^.+/?(/.*.php)$ $1 last;
        rewrite ^(.+)$ /index.php?q=$1 last;
        access_log off;
        expires max;
        break;
    }
}
## WordPress-Forum
if (!-e $request_filename) {
    rewrite ^/forums/topic/(.*)$ /forums/topic.php?q=$1 last;
    rewrite ^/forums/forum/(.*)$ /forums/forum.php?q=$1 last;
    rewrite ^/forums/profile/(.*)$ /forums/profile.php?q=$1 last;
    rewrite ^/forums/view/(.*)$ /forums/view.php?q=$1 last;
    rewrite ^/forums/tags/(.*)$ /forums/tags.php?q=$1 last;
    rewrite ^/forums/rss/(.*)$ /forums/rss.php?q=$1 last;
    rewrite ^/forums/bb-admin/ /forums/bb-admin/index.php last;
    rewrite ^/forums/ /forums/index.php last;
    break;
}
## Feedburner
if ($http_user_agent !~ FeedBurner) {
    rewrite ^/comment/feed/?$ http://feeds.feedburner.com/domain last;
    rewrite ^/feed/?$ http://feeds.feedburner.com/domain last;
}
## WordPress W3 Total Cache
set $totalcache_file '';
set $totalcache_uri $request_uri;
if ($request_method = POST) {
    set $totalcache_uri '';
}
if ($query_string) {
    set $totalcache_uri '';
}
if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
    set $totalcache_uri '';
}
if ($totalcache_uri ~ ^(.+)$) {
    set $totalcache_file /wp-content/w3tc-$http_host/pgcache/$1/_default_.html;
}
if (-f $document_root$totalcache_file) {
    rewrite ^(.*)$ $totalcache_file break;
}

ggf. kann man auch gzip-Dateien ausgeben lassen: set $totalcache_file /wp-content/w3tc$http_host/pgcache/$1/_default_.html.gzip;

## WordPress SuperCache
set $supercache_file '';
set $supercache_uri $request_uri;
if ($request_method = POST) {
    set $supercache_uri '';
}
if ($query_string) {
    set $supercache_uri '';
}
if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
    set $supercache_uri '';
}
if ($supercache_uri ~ ^(.+)$) {
    set $supercache_file /wp-content/cache/supercache/$http_host/$1index.html;
}
if (-f $document_root$supercache_file) {
    rewrite ^(.*)$ $supercache_file break;
}
if (!-e $request_filename) {
    rewrite . /index.php last;
}
location ~* ^.+.(htm|html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
    access_log off;
    expires max;
    root /var/www/www.domain.de/web/;
}
## .htaccess & .htpassword sperren
location ~ /\.ht {
    deny  all;
}


Weitere Infos findest du im Wiki von nginx: wiki.nginx.org/Wordpress

Debian/Ubuntu Paket selber bauen (Nginx)

Heute zeige ich, wie du dir deinen eigenen Webserver (Nginx) als .deb-Paket bauen und installieren kannst… :-) In einem vorherigen Beitrag hatte ich bereits beschrieben, wie du PHP5-fpm mit Nginx installieren kannst. Da ich folgenden Fehler bei dem Update auf Version 0.9.1 bekommen habe ->


Can't locate nginx.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.10.1 /usr/local/share/perl/5.10.1 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .).
BEGIN failed--compilation aborted. 


<- wurde das deb-Paket kurzerhand neu-gebaut und zwar ohne Perl-Unterstützung. :-)


1.) Root werden und einiges ggf. nachinstallieren + die Quellen (deb-src) herunterladen

sudo bash
aptitude install build-essential devscripts fakeroot debhelper autotools-dev libpcre3-dev zlib1g-dev libssl-dev
mkdir /usr/src/nginx ; cd !$
apt-get source nginx
cd $(ls -d nginx*/)

2.) Ggf. schauen, ob es bereits eine neue Version gibt und diese herunterladen und abgleichen

wget http://sysoev.ru/nginx/nginx-0.9.1.tar.gz
export DEBFULLNAME='nginx';export DEBEMAIL='deine@email-adresse.de'; uupdate --upstream-version 0.9.1 ../nginx-0.9.1.tar.gz
cd ../$(dpkg-parsechangelog | sed -n 's/^Source: //p')-0.9.1
sed -i '/^Maintainer/s/: .*/: dein_name /;/^Uploaders/s/: .*/: dein_name /;/XSBC-Original-Maintainer/d' debian/control;

3.) die ./configure Variablen ggf. an deine Bedürfnisse anpassen (debian/rules)

vim debian/rules
config.status: config.sub config.guess
        ./configure \
            --conf-path=/etc/nginx/nginx.conf \
            --user=wwddw-data \
            --group=www-data \
            --sbin-path=/usr/sbin/nginx \
            --pid-path=/var/run/nginx.pid \
            --with-sha1-asm \
            --with-zlib-asm=pentiumpro \
            --with-md5-asm \
            --with-ld-opt="-L /usr/lib" \
            --with-cc-opt="-D FD_SETSIZE=2048" \
            --with-cc-opt="-I /usr/include" \
            --with-cpu-opt="opteron" \
            --error-log-path=/var/log/nginx/error.log \
            --http-client-body-temp-path=/var/lib/nginx/body \
            --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
            --http-log-path=/var/log/nginx/access.log \
            --http-proxy-temp-path=/var/lib/nginx/proxy \
            --http-scgi-temp-path=/var/lib/nginx/scgi \
            --http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
            --lock-path=/var/lock/nginx.lock \
            --pid-path=/var/run/nginx.pid \
            --with-debug \
            --with-http_dav_module \
            --with-http_flv_module \
            --with-http_geoip_module \
            --with-http_gzip_static_module \
            --with-http_image_filter_module \
            --with-http_realip_module \
            --with-http_stub_status_module \
            --with-http_ssl_module \
            --with-http_sub_module \
            --with-http_xslt_module \
            --with-ipv6 \
            --with-sha1=/usr/include/openssl \
            --with-md5=/usr/include/openssl \
            --with-mail \
            --with-mail_ssl_module \
            --add-module=$(CURDIR)/modules/nginx-upstream-fair \
            --add-module=$(CURDIR)/modules/nginx-echo \
            $(CONFIGURE_OPTS) >$@
        touch $@
Ich habe einige Module deaktiviert welche ich nicht benötige, SSL-Verschlüsselung + IPv6 + … aktiviert und unter anderem Optimierungen für meine CPU aktiviert. Unter folgendem Link, findest du alle Module, welche standardmäßig bei “nginx” mitgeliefert werden:
vim debian/control
In dieser Datei muss man ggf. noch Abhängigkeiten ergänzen oder entfernen. In meinem Fall habe ich die perl-lib entfernt, da ich dies auch aus der zu-vorigen Konfiguration entfernt hatte.

4.) Ggf. die Konfiguration ändern bzw. deine eigene übernehmen (debian/conf/)

Dafür änderst du einfach die Dateien unter “debian/conf/” und sobald du das fertige Paket installierst, wird deine Konfiguration übernommen, dies kann auch sehr hilfreich sein, wenn du das selbe Programm mit den selben oder ähnlichen Konfiguration auf verschiedenen Computern installierst.

export DEBFULLNAME='nginx';export DEBEMAIL='deine@email-adresse.de';debuild -i -us -uc

5.) Installiere dein neues Debian-Paket :-)

cd ..
dpkg -i nginx_0.9*deb && sudo aptitude hold nginx
Anbei noch meine Nginx-Version ->
Du kannst .deb-Dateien auch entpacken, wenn du diese genauer anschauen möchtest.
ar -x nginx_0.9.1-ppa3_i386.deb
tar xzvf data.tar.gz
Links:

Nginx + PHP5-fpm auf Debian/Ubuntu

Zurück zur “Webseiten beschleunigen” – Übersicht

5.3) Nginx als Webserver


nginx_logo

Wer komplett auf nginx als Webserver umsteigen will kann dies auch sehr einfach bewerkstelligen. Ich persönlich nutzte diese Methode und es laufen mehrere WordPress-Webseiten, e107, DokuWiki u.s.w. tadellos mit diesem System.

Als erstes müssen wir unsere sources.list ein wenig erweitern… um php5-fpm direkt mit dem Projektmanager installieren zu können, wie dies Funktioniert habe ich bereits in einem anderen Beitrag beschreiben: php-5-FPM

Danach installieren wir nginx (Webserver) + PHP, wenn du noch apache2 oder einen anderen Webserver, welcher auf Port 80 lauscht installiert hast, musst du diesen nun deinstallieren bzw. erst einmal stoppen und ggf. einige libraries nachinstallieren, falls du Ubuntu und nicht Debian nutzt.


ggf. nur bei Ubuntu

wget http://us.archive.ubuntu.com/ubuntu/pool/main/k/krb5/libkrb53_1.6.dfsg.4~beta1-5ubuntu2_i386.deb
wget http://us.archive.ubuntu.com/ubuntu/pool/main/i/icu/libicu38_3.8-6ubuntu0.2_i386.deb
sudo dpkg -i *.deb

ggf. root-Rechte

sudo bash

ggf. apache stoppen

/etc/init.d/apache2 stop
aptitude install nginx php5-fpm

Nun kommen wir zur Konfiguration, ich poste hier einfach mal meine komplette Konfig, daher sollte diese ohne Probleme lauffähig sein, wenn du die aktuelle Version installiert hast.

vim /etc/nginx/nginx.conf
user www-data;
worker_processes 4;
worker_rlimit_nofile 3000;
pid /var/run/nginx.pid;

# [ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log;

#google_perftools_profiles /tmp/profile/;

events {
        worker_connections 2048;
        # use [ kqueue | rtsig | epoll | /dev/poll | select | poll ] ;
        use epoll;
        multi_accept on;
}

http {
        server_names_hash_bucket_size 64;

        ## Size Limits
        client_max_body_size        10M;
        client_header_buffer_size   32k;
        client_body_buffer_size     128k;
        large_client_header_buffers 64 8k;

        ## Timeouts
        client_body_timeout   3m;
        client_header_timeout 3m;
        send_timeout          3m;
        #expires              24h;
        keepalive_timeout     120 120;

        ## General Options
        ignore_invalid_headers   on;
        keepalive_requests       100;
        limit_zone normal $binary_remote_addr 5m;
        recursive_error_pages    on;
        sendfile                 on;
        server_name_in_redirect  off;
        server_names_hash_max_size 512;
        server_tokens            off;
        set_real_ip_from 127.0.0.1;
        real_ip_header X-Forwarded-For;

        ## TCP options
        #tcp_nopush on;
        tcp_nodelay off;
        #send_lowat 12000;

        include mime.types;
        default_type application/octet-stream;

        access_log /var/log/nginx/access.log;

        log_format main '$remote_addr - $remote_user [$time_local] $status '
        '\"$request\" $body_bytes_sent \"$http_referer\" '
        '\"$http_user_agent\" \"http_x_forwarded_for\"';

        ## Cache
        open_file_cache max=1000 inactive=24h;
        open_file_cache_valid    24h;
        open_file_cache_min_uses 2;
        open_file_cache_errors   on;

        ## Compression
        gzip              on;
        gzip_static       on;
        gzip_disable      "MSIE [1-6]\.";
        gzip_buffers      32 8k;
        gzip_comp_level   5;
        gzip_http_version 1.0;
        gzip_min_length   0;
        gzip_proxied      any;
        gzip_types text/plain text/css text/xml text/javascript application/json application/xml application/xml+rss application/x-javascript image/x-icon application/x-perl application/x-httpd-cgi;
        gzip_vary         on;

        output_buffers   10 128k;
        postpone_output  1500;

        # Beispiel: Loadbalance
        #upstream webbackend  {
                #ip_hash;
                #server web1.domain.lan weight=10 max_fails=3 fail_timeout=30s;
                #server web2.domain.lan weight=1 backup;
        #}

        # Beispiel: Reverse-Proxy
        #server {
                #access_log  /var/log/nginx/access.proxy.log main;
                #error_log   /var/log/nginx/error.proxy.log;
                #listen      80;
                #server_name _;

                ## PROXY - Web
                #location ~ \.php$ {
                        #proxy_cache            cache;
                        #proxy_pass  http://127.0.0.1:8080;
                #}
        #}

        # Beispiel: HTTP Server (sollte jedoch besser unter /etc/nginx/sites-available/ angelegt werden)
        #server {
                #listen       80;
                #listen       somename:80;
                #server_name  somename  alias  another.alias;

                #location / {
                        #root   html;
                        #index  index.html index.htm;
                        #}
                #}

        # Beispiel: HTTPS Server (sollte jedoch besser unter /etc/nginx/sites-available/ angelegt werden)
        #server {
                #listen       443;
                #server_name  localhost;

                #ssl                  on;
                #ssl_certificate      cert.pem;
                #ssl_certificate_key  cert.key;

                #ssl_session_timeout  5m;

                #ssl_protocols  SSLv2 SSLv3 TLSv1;
                #ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
                #ssl_prefer_server_ciphers   on;

                #location / {
                #root   html;
                #index  index.html index.htm;
                #}
        #}

#include /etc/nginx/proxy.conf;
include /etc/nginx/sites-enabled/*.conf;
}
vim /etc/nginx/proxy.conf
proxy_buffering            on;
proxy_cache_min_uses       3;
proxy_cache_path           /usr/local/nginx/proxy_cache/ levels=1:2 keys_zone=cache:10m inactive=24h max_size=1000M;
proxy_cache                cache;
proxy_cache_valid          200 24h;
proxy_cache_use_stale      error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_ignore_client_abort  off;
proxy_intercept_errors     on;
proxy_next_upstream        error timeout invalid_header;
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;
proxy_buffers              32 1M;
proxy_busy_buffers_size    31M;
proxy_temp_file_write_size 30M;
proxy_buffer_size          30M;
proxy_connect_timeout      90;
proxy_send_timeout         90;
proxy_read_timeout         90;
proxy_ignore_headers       Expires Cache-Control;

so nun richten wir unsere erste Webseite ein… (domain.de muss in den nachfolgenden Howto durch deine eigene Domain ersetzt werden und natürlich für jede neue Werbepräsenz eine neue Datei angelegt werden.

cd /etc/nginx/sites-available/
vim domain.de.conf
server {
        server_name domain.de www.domain.de *.domain.de;
        root /var/www/www.domian.de/web/;
        listen 80;
        index index.php;
        access_log /var/log/nginx/www.domian.de.access.log main;
        error_log /var/log/nginx/www.domian.de.error.log;

        if (-f $request_filename) {
                break;
        }

        location / {
                try_files $uri $uri/ @domian;
        }

        location ~* ^.+.(htm|html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
                access_log off;
                expires max;
                root /var/www/www.domian.de/web/;
        }

        location @domian {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_param SCRIPT_FILENAME $document_root/index.php;
                include /etc/nginx/fastcgi_params;
                fastcgi_param SCRIPT_NAME /index.php;
        }

        location ~ \.php$ {
                try_files $uri @domian;
                fastcgi_index index.php;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /etc/nginx/fastcgi_params;
        }

        location ~ /\.ht {
                deny  all;
        }
}
vim /etc/nginx/fastcgi_params
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

fastcgi_param  REDIRECT_STATUS    200;

nun müssen wir die Webseite nur noch aktivieren, indem wir die soeben erstellte Datei verlinken.

cd /etc/nginx/sites-enabled/
ln -s ../sites-available/domain.de.conf .
nginx -t
/etc/init.d/nginx restart

Und schon läuft unser neuer Webserver. :-) Um die neuste Version von Nginx auf Debian/Ubuntu zu installieren kann man ggf. noch folgende Quellen in die “sources.list” eintragen.

echo "deb  http://ppa.launchpad.net/nginx/stable/ubuntu lucid main" >> /etc/apt/sources.list
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C
apt-get update
apt-get install nginx

… oder du verwendest die letzte Development-Version:

echo "deb  http://ppa.launchpad.net/nginx/development/ubuntu lucid main" >> /etc/apt/sources.list
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C
apt-get update
apt-get install nginx

Nun müssen wir PHP5-FPM noch ein wenig anpassen, so dass php-fpm mit den Rechten des jeweilligen Webs ausgeführt wird:

mkdir /etc/php5/fpm/pools/
vim /etc/php5/fpm/php5-fpm.conf
[...]
[global]
pid = /var/run/php5-fpm.pid
error_log = /var/log/php-fpm.log
log_level = notice
emergency_restart_threshold = 10
emergency_restart_interval = 1m
process_control_timeout = 5s
daemonize = yes

;  pools defined in virtual hosts
include=/etc/php5/fpm/pools/*.conf
[..]

Nun leben wir für eine Webseite eine PHP-Konfiguration an:

vim /etc/php5/fpm/pools/domain.conf
[domain]

; one Port for one Website
listen = 127.0.0.1:11000

; uid/gid
user = domain_user
group = domain_group

; logging
request_slowlog_timeout = 5s
slowlog = /var/log/slowlog-domain.log

; Choose how the process manager will control the number of child processes.
pm.max_children = 10
pm.start_servers = 5
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 500

; Pass environment variables
env[TMP] = /var/www/www.domain.de/phptmp
env[TMPDIR] = /var/www/www.domain.de/phptmp
env[TEMP] = /var/www/www.domain.de/phptmp

; inculde defaults
include = /etc/php5/fpm/common.conf

; host-specific php ini settings here
;php_admin_value[open_basedir] =
vim /etc/php5/fpm/common.conf
listen.backlog = -1
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.status_path = /status
ping.path = /ping
ping.response = pong
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[HOSTNAME] = $HOSTNAME
env[PATH] = /bin:/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/usr/sbin
Jetzt läuft der PHP-fpm Prozess mit den Rechten des jeweiligen Users und mit eigenem Tmp-Verzeichnis, wer will kann php-fpm sogar in einer chroot-Umgebung ausführen lassen :-)
Links:

Webseiten Analyse

Zurück zur “Webseiten beschleunigen” – Übersicht

1.) Webseiten Analyse

Dies ist der Erste Teil von meiner Blog-Reihe “Webseiten beschleunigen”. Um die ursprüngliche Ladegeschwindigkeit deiner Webseite zu prüfen, installieren wir uns zwei Erweiterungen für Firefox.

Firebug +
YSlow

ggf. kann man sich auch nach die nachfolgenden Links anschauen, jedoch habe ich mit der Kombination „ Firebug + YSlow“ sehr gute Erfahrungen gemacht, daher folgt nun diesbezüglich ein kleines Video.

 

 

Alternative von Google:

Firebug +
Page-Speed

 

Alternative Online-Analyse:

Bisher habe ich nur zwei Online-Analyse-Dienste gefunden, welche mir wirklich geholfen haben.

a.) Auf Pingdom.com kannst du die Ladezeit deiner Webseite und dessen Inhalt sehr schön in einem Graphen sehen und Schwachstellen somit sehr einfach erkennen, z.B. wenn eine externe Datei nicht erreichbar ist.

tools.pingdom.com

 

pingdom
pingdom

 

b.) Die nächste Webseite ist AOL’s WebPageTest ist ein wenig umfangreicher, so zeigt diese Webseite wie bereits beim vorherigen Link einen Graphen mit den geladen Dateien an, jedoch führt diese Webseite den Test zweimal durch, so dass die Auswirkung vom Browser-Cache simuliert wird. Außerdem gibt es eine Checkliste, wo alle Dateien noch einmal einzeln geprüft werden.

AOL’s WebPageTest

 

aol_webpagetest
aol_webpagetest

 

1.1) Webseiten Benchmark

Außerdem könnte kann die Abfragen auch direkt von der Shell aus starten z.B. mit “httperf”. Es folgt ein kleines HowTo für Debian:

sudo bash
aptitude install httperf
httperf --hog --server voku-online.de --num-conn 20 --ra 10 --timeout 5

jedoch kann ich zumindest mit der Ausgabe nicht viel anfangen, da mir diese vielen Zahlen auf Anhieb nicht viel sagen, daher folgt eine kleine Anleitung, wie man aus diesen Werten einen Graphen zeichnet

cd /usr/src/
wget http://www.xenoclast.org/autobench/downloads/debian/autobench_2.1.2_i386.deb
dpkg -i autobench_2.1.2_i386.deb
autobench --single_host --host1  www.test.de --uri1 /10K --quiet
--low_rate 20  --high_rate 200 --rate_step 20 --num_call 10
--num_conn  5000 --timeout 5 --file results.tsv
aptitude install gnuplot
bench2graph results.tsv result.ps

so nun laden wir die Datei „result.ps“ z.B. per WinSCP auf unsern Windows Rechner und öffnen die Datei mit Ghostscript

Hier mein Beispiel:

 

webserver_bench
webserver_bench

 

(1) req_rate: request rate, requests per second
(2) con_rate: connection rate, connections per second
(3) min_rep_rate: minimum reply rate, replies per second
(4) avg_rep_rate: average reply rate, replies per second
(5) max_rep_rate: maximum reply rate, replies per second
(6) stddev_rep_rate: standard deviation for reply rate
(7) resp_time
(8) net_io: Net I/O, KB per second
(9) error

Link:
autobench

 

Anstatt diesen Vorgang komplett per Hand zu bewerkstelligen, kann man auch folgende Webseite dazu nutzen:

-> loadimpact.com

So kannst du herausfinden, wie sich deine Webseite verhält, wenn sehr viele Besucher diese besuchen. Anbei das Ergebnis von diesem Blog. (Nach meiner Optimierung per “PHP XCache” + “Nginx” + “W3 Total Cache

 

loadimpact

 

Hier ist ein schneller Überblick darüber, was diese Kurve nun aussagt. -> loadimpact.com/forum/

Webserver beschleunigen

Zurück zur “Webseiten beschleunigen” – Übersicht

5.) Webserver beschleunigen

5.1) Apache-Module deaktivieren


Ggf. kann man auch einige Module (Erweiterungen) von Apache abschaltet, wer z.B. auf seiner Webseite gar keine SSL-Verschlüsselung verwendet, könnte das entsprechende Modul deaktivieren.

a2dismod  ssl
/etc/init.d/apache2 restart

Die momentan aktiven Erweiterungen kann man unter “/etc/apache2/mods-enabled/” einsehen, die installierten Erweiterungen sind unter “/etc/apache2/mods-available/” zu finden.

Dynamische Seiten:
mod_log_config erlaubt die access_log-Dateien in div. Formaten.
mod_cgi braucht man, wenn man CGI zulassen will.
mod_suexec erlaubt CGIs als ein bestimmter User zu laufen.
mod_perl braucht man nicht um Perl als CGI auszuführen!
mod_php5 ist schneller als suphp (aber nicht so sicher).
mod_suphp führt php Skript mit den Rechten des entsprechenden webs aus.
mod_include erlaubt die Verwendung von SSI.

URL-Manipulationen:
mod_alias braucht man zum Einblenden von virtuellen Verzeichnissen.
mod_rewrite erlaubt URL-Manipulationen, kostet aber Performance.
mod_autoindex & mod_dir erlauben eine Navigation ohne index.html
mod_userdir erlaub User-URLs mit z.B.: www.huschi.net/~huschi/
mod_negotiation analysiert Accept-Anfragen.
mod_vhost_alias erlaubt das Anlegen von virtuellen Hosts.

Environment- & Header-Manipulation:
mod_mime setzt automatisch den richtigen Header anhand der Dateiendung.
mod_env & mod_setenvif erlauben die modifizierung von ENV-Variablen.
mod_expires erlaubt die HTTP-Header Manipulation des Expires-Date (Verfall-Zeit).
mod_ssl erlaubt die Verwendung von SSL (https).

Zudem kann man folgende Option in der Apache-Konfiguration ändern, so dass man DNS-Lookups reduziert.

vim /etc/apache2/apache2.conf

HostNameLookups off

5.2) Reverse Proxy (Nginx)

nginx_logo
Wir wollen unsere Webseite mal wieder ein wenig beschleunigen, dies können wir auf verschiedenen Wegen bewerkstelligen, heute beschäftigen wir uns mit dem Reverse-Proxy vor einem Webserver, in diesem Beispiel nutzen wir für diesen Zweck Nginx + apache2. Der große Vorteil von einen Proxy vor dem Webserver ist, dass mehrere Anfragen gleichzeitig gestellt werden könne, um die Performance von statischen Daten zu steigern. Die Anfragen an dynamische Inhalte werden dann noch immer an einen zweiten bzw. an mehrere Webserver, hinter dem Proxy weitergereicht.

Wer sich jetzt fragt, warum man nicht komplett auf Nginx umsteigen sollte, da die Benchmarks zeigen, dass dieser schneller ist als der Apache Webserver, derjenige hat nicht bedacht, dass bei diesen Tests nur die Reaktionen des Webservers auf eine gewisse Anzahl von Anfragen geprüft wird, wenn man jedoch mit “nginx + fcgi” viele php-Dateien verarbeiten möchte, ist ein “apache + mod_php” schneller, zudem kann man diese Daten z.B. mittels eAccelerator zusätzlich cachen, was die Geschwindigkeit von php-Daten noch einmal positiv beeinflusst.

Update: Inzwischen konnte ich die ganzer Sache ausgiebig testen und setzte momentan eine Kombination aus “Varnish” + “Nginx” + “php5-fpm” (+ xcache) ein, so werden die Seiten von Varnish zwischengespeichert alle neue Anfragen von Nginx entgegengenommen, Bilder etc. sofort ausgeliefert und PHP-Anfragen an einen laufendem PHP-Daemon weitergereicht, jedoch erst-einmal zurück zum Beispiel mit Nginx als Reverse-Proxy…

Als Lösung für diese Problem habe ich mir einen Nginx-Proxy gebastelt, der statische Daten (Bilder…) ausliefert und diese zusätzlich für 24 Stunden zwischenspeichert, alle andern dynamischen Inhalte (php,cgi…) werden sofort an apache durch-gereicht. In diesem Beispiel laufen sowohl der Proxy als auch Apache auf einem Server.
reverse_proxy

5.2.1.) Apache auf einem neuen Port laufen lassen

Folgende Datei öffnen…

vim /etc/apache2/ports.conf

…Port “80” durch z.B. “127.0.0.1:8080” ersetzen.

[stextbox id=”warning”]!!! Wichtig ist hier, darauf zu achten, dass der Apache selber nicht mehr über eine Öffentliche IP-Adresse erreichbar ist. !!![/stextbox]

Ggf. helfen dir die folgenden Zeilen weiter, um alle Einträge in einer Datei zu Ändern (mit vi / vim).

:%s/^80/127.0.0.1:8080/g

:%s/SERVER_IP_ADRESSE:80/127.0.0.1:8080/g

SERVER_IP_ADRESSE muss nun noch mit der IP-Adresse des Servers ersetzte werden und anschließend musst du den Apache Webserver noch neu-starten. Ggf. müssen noch weitere Dateien von Apache angepasst werden.

Mit dem folgendem Befehl kannst du prüfen, ob noch weitere Einträge (Port 80) in der Apache Konfiguration sind.

/bin/grep -wr 80 /etc/apache2/


5.2.2) Ggf. ISPConfig anpassen

Falls du z.B. ISPConfig installiert hat, werden wie Änderungen am Apache Webserver, bei der nächsten Änderung über die Admin-Oberfläche wieder verworfen, daher müssen wir das Template von ISPConfig dementsprechend anpassen.

vim ~/ispconfig/isp/conf/vhost.conf.master

NameVirtualHost 127.0.0.1:8080


5.2.3.) Reverse-Proxy: nginx installieren & konfigurieren

aptitude install nginx
vim /etc/nginx/nginx.conf
user www-data;
worker_processes 4;
worker_rlimit_nofile 3000;
pid /var/run/nginx.pid;

# [ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log;

#google_perftools_profiles /tmp/profile/;

events {
        worker_connections 2048;
        # use [ kqueue | rtsig | epoll | /dev/poll | select | poll ] ;
        use epoll;
        multi_accept on;
}

http {
        server_names_hash_bucket_size 64;

        ## Size Limits
        client_max_body_size        10M;
        client_header_buffer_size   32k;
        client_body_buffer_size     128k;
        large_client_header_buffers 64 8k;

        ## Timeouts
        client_body_timeout   3m;
        client_header_timeout 3m;
        send_timeout          3m;
        #expires              24h;
        keepalive_timeout     120 120;

        ## General Options
        ignore_invalid_headers   on;
        keepalive_requests       100;
        limit_zone normal $binary_remote_addr 5m;
        recursive_error_pages    on;
        sendfile                 on;
        server_name_in_redirect  off;
        server_names_hash_max_size 512;
        server_tokens            off;
        set_real_ip_from 127.0.0.1;
        real_ip_header X-Forwarded-For;

        ## TCP options
        #tcp_nopush on;
        tcp_nodelay off;
        #send_lowat 12000;

        include mime.types;
        default_type application/octet-stream;

        access_log /var/log/nginx/access.log;

        log_format main '$remote_addr - $remote_user [$time_local] $status '
        '\"$request\" $body_bytes_sent \"$http_referer\" '
        '\"$http_user_agent\" \"http_x_forwarded_for\"';

        ## Cache
        open_file_cache max=1000 inactive=24h;
        open_file_cache_valid    24h;
        open_file_cache_min_uses 2;
        open_file_cache_errors   on;

        ## Compression
        gzip              on;
        gzip_static       on;
        gzip_disable      "MSIE [1-6]\.";
        gzip_buffers      32 8k;
        gzip_comp_level   5;
        gzip_http_version 1.0;
        gzip_min_length   0;
        gzip_proxied      any;
        gzip_types text/plain text/css text/xml text/javascript application/json application/xml application/xml+rss application/x-javascript image/x-icon application/x-perl application/x-httpd-cgi;
        gzip_vary         on;

        output_buffers   10 128k;
        postpone_output  1500;

        # Beispiel: Loadbalance
        #upstream webbackend  {
                #ip_hash;
                #server web1.domain.lan weight=10 max_fails=3 fail_timeout=30s;
                #server web2.domain.lan weight=1 backup;
        #}
        # Beispiel: Reverse-Proxy
        #server {
                #access_log  /var/log/nginx/access.proxy.log main;
                #error_log   /var/log/nginx/error.proxy.log;
                #listen      80;
                #server_name _;

                ## PROXY - Web
                #location ~ \.php$ {
                        #proxy_cache            cache;
                        #proxy_pass  http://127.0.0.1:8080;
                #}
        #}

        # Beispiel: HTTP Server (sollte jedoch besser unter /etc/nginx/sites-available/ angelegt werden)
        #server {
                #listen       8000;
                #listen       somename:8080;
                #server_name  somename  alias  another.alias;

                #location / {
                        #root   html;
                        #index  index.html index.htm;
                        #}
                #}

        # Beispiel: HTTPS Server (sollte jedoch besser unter /etc/nginx/sites-available/ angelegt werden)
        #server {
                #listen       443;
                #server_name  localhost;

                #ssl                  on;
                #ssl_certificate      cert.pem;
                #ssl_certificate_key  cert.key;

                #ssl_session_timeout  5m;

                #ssl_protocols  SSLv2 SSLv3 TLSv1;
                #ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
                #ssl_prefer_server_ciphers   on;

                #location / {
                #root   html;
                #index  index.html index.htm;
                #}
        #}

include /etc/nginx/proxy.conf;
include /etc/nginx/sites-enabled/*.conf;
}
vim /etc/nginx/proxy.conf
proxy_buffering            on;
proxy_cache_min_uses       3;
proxy_cache_path           /usr/local/nginx/proxy_cache/ levels=1:2 keys_zone=cache:10m inactive=24h max_size=1000M;
proxy_cache                cache;
proxy_cache_valid          200 24h;
proxy_cache_use_stale      error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_ignore_client_abort  off;
proxy_intercept_errors     on;
proxy_next_upstream        error timeout invalid_header;
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;
proxy_buffers              32 1M;
proxy_busy_buffers_size    31M;
proxy_temp_file_write_size 30M;
proxy_buffer_size          30M;
proxy_connect_timeout      90;
proxy_send_timeout         90;
proxy_read_timeout         90;
proxy_ignore_headers       Expires Cache-Control;
mkdir /usr/local/nginx/proxy_cache/
chown -R www-data:www-data /usr/local/nginx/proxy_cache/

Link:
wiki.nginx.org/NginxHttpProxyModule

/etc/init.d/apache2 restart
/etc/init.d/nginx restart

Nginx läuft nun auf Port 80 und nimmt die Anfragen von Client an und der Apache wartet auf die weitergeleiteten Anfragen von Reverse-Proxy.

[stextbox id=”info”]Bei mir hat der cache (Zwischenspeicherung) jedoch Probleme verursacht, so dass Captcha’s nicht mehr funktioniert haben, daher habe ich diesen im Nachhinein abgeschaltet.[/stextbox]


Links:
www.joeandmotorboat.com/2008/02/28/apache-vs-nginx


5.2.4.) Logfiles korrigieren

Nun stehen wir noch vor dem Problem, dass im Logfile von apache die IP-Adresse vom Reverse-Proxy auftauscht und zwar nur noch diese, um dies zu umgehen installieren wir nun noch folgendes…

aptitude install libapache2-mod-rpaf

Nun noch folgendes in den Vhost-Einträgen bzw. in dem ISPConfig Template ergänzen.


RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1

/etc/init.d/apache2 reload

…und schon haben wir einen Reverse-Proxy (“Apache” + “Nginx”) installiert. Unter Punkt 5.3 zeige ich wie du ganz auf Nginx setzten kannst und somit nicht zwei Webserver, betreiben & konfigurieren musst.

Webseiten beschleunigen – Übersicht

Der Artikel beschreibt, wie man seine Webseite bzw. seinen Server analysiert und optimiert um Performance zu gewinnen, Ladezeit zu reduzierten bzw. Traffic einzusparen. Man kann einiges an Performance gewinnen, indem man z.B. Bilder im richtigen Format abspeichert bzw. komprimiert, CSS- / JS-Dateien kombiniert und ebenfalls komprimiert oder auch bestimmt Daten vorkomprimiert zur Verfügung stellt.

1.) Webseiten Analyse
1.1) Webseiten Benchmark

2.) Komprimierung
2.1) Bilder komprimieren
2.1.1) Bilder Sprites
2.1.2) PNG-Bilder komprimieren
2.1.3) JPEG-Bilder komprimieren
2.1.4) Bilder komprimieren – Online
2.2) JavaScript/CSS komprimieren
2.2.1) JavaScript/CSS komprimieren – serverseitig
2.2.2) JavaScript/CSS komprimieren – Online
2.3) Apache gzip-Kompression
2.3.1) Aktiviere mod_deflate (gzip) – serverseitig
2.3.2) Aktiviere mod_gzip – serverseitig
2.3.3) Aktiviere gzip – manuell

3.) JavaScript richtig im HTML-Code platzieren

4.) Browser-Cache nutzen
4.1) Browser-Cache manuell einstellen
4.2) Browser-Cache serverseitig einstellen

5.) Webserver beschleunigen
5.1) Apache-Module deaktivieren
5.2) Reverse Proxy (Nginx)
5.3) Nginx als Webserver
5.4) Nginx mit Varnish (Proxy)

6.) PHP optimieren/caching
6.1) PHP-Daten zwischenspeichern
6.2) SQL-Abfrage mittels PHP zwischenspeichern
6.3) PHP-Module deaktivieren
6.4) php.ini (Konfiguration) optimieren

7.) MySQL optimieren
7.1) MariaDB (MySQL-Fork)


Zusammenfassung

Abschließend möchte ich diesen Thema noch einmal kurz zusammenfassen, so dass man ggf. selber weitere Möglichkeiten erkennt, die Ladegeschwindigkeit seiner Webseite zu verbessern, jedoch nicht auf die Technische Umsetzung eingehen.

Kenne deinen Feind !!!

80 bis 90% der schlechten Performance liegt an der Webseite selber und nicht auf der Serverseite, solange nur wenig Besucher auf deiner Webseite sind, braucht man sich eigentlich um einen Revere-Proxy oder eine alternative zu Apache keine oder zumindest nur wenig Gedanken machen, da die Performance erst mit steigender Besucherzahl einbricht. Jedoch sollte man in jedem Fall die gzip-Komprimierung und den Browser-Cache nutzen.

Externe Dateien (Bilder, JS, CSS, Videos…)

Jeder Aufruf einer Datei kostet Performance und Bandbreite, daher sollte man im allgemeinen weniger Requests produzieren, indem man z.B. JS- bzw. CSS-Dateien kombiniert. Dieser negative Einwirkung steigt dramatisch bei externen Dateien von andern Servern und besonders dann, wenn dieser gerade mal nicht erreichbar ist.

Scripte

Immer wenn eine Browser eine Webseite abruft und im HTML-Code ein Script finde, wird das weitere laden der Webseite eingestellt und erst-einmal die JavaScript Engine damit beansprucht, diesen zu interpretieren. Daher sollte man diese Dateien erst am Ende der Webseite laden lassen, so dass der User die Webseite früher sehen kann, auch wenn z.B. die Animation des Menüs erst nach nachgeladen werden muss. Mit diesem Ansatz, erscheint es nur Sinnvoll CSS-Daten am Anfang laden zu lassen, so dass sich die Webseite dem User direkt im korrektem Layout präsentiert.

Bilder

Ein weites großer Bereich sind Bilder, dabei muss man jedoch ein gutes Mittelmaß an Text und Bildern finden, da die User zwar Bilder immer schön finden.. Logo, Hintergrundbild u.s.w. jedoch macht es nur wenig Sinn seine selbst jeder kleine Datei zu optimieren, wenn man oben über der Webseite ein 300 KB großes Bild eingefügt hat. Wie bereit im Artikel beschrieben gibt es jedoch zahlreiche Methoden (PNG- und JPEG-Dateien) diese zu optimieren.

Yahoo hat zudem eine sehr umfassende Liste von weiteren Regeln zusammengestellt, welche man beachten sollte.