Drupal 7.7 mit Boost und nginx beschleunigen (Debian Squeeze)

Version 1.0

Author: Falko Timme , Christian Schmalfeld <c [dot] schmalfeld [at] projektfarm [dot] de>
Follow me on Twitter

Dieses Tutorial zeigt Ihnen, wie Sie Drupal 7.7 auf Ihrem LAMP-Stapel (Debian Squeeze) mit Hilfe von Boost und nginx beschleunigen können. Boost bietet statisches Seitencaching für Drupal, dies resultiert in einer signifikanten Erhöhung der Arbeitsleistung und Skalierbarkeit für Seiten, welche größtenteils anonymen Traffic erhalten. Es stellt außerdem sicher, dass Ihre eingeloggten Benutzer stetig mit neuem Inhalt versorgt werden, indem es die Seiten für jene nicht cached. Im ersten Schritt werde ich Ihnen zeigen, wie Sie Ihre Seite durch Boost auf einem normalen LAMP-Stapel (Apache2, PHP, MySQL) schneller machen, im zweiten Schritt zeige ich Ihnen wie Sie die Seite sogar noch schneller machen, indem Sie nginx als Reverse Proxy vor Apache setzen, sodass es die statischen, von Boost gecacheten HTML Dateien liefert. nginx liefert statische Dateien sehr viel schneller als Apache und verbraucht dabei weniger RAM/CPU.

Ich gebe für den Inhalt des Tutorials keinerlei Garantie!

1 Vorbemerkung

Ich benutze hierfür einen normalen LAMP-Stapel unter Debian Squeeze, aufgesetzt wie zum Beispiel in diesem Tutorial:  Apache2 mit PHP5 und MySQL Unterstützung unter Debian Squeeze installieren (LAMP) . Meine Drupal 7.7 Installation benutzt die Domains www.example.com und example.com, mein Dokumentpfad ist /var/www/www.example.com/web.

Ich nehme an, dass Sie bereits eine funktionierende Drupal 7.7 Installation haben, welche saubere URLs benutzt.

Stellen Sie sicher, dass die Apache Module rewrite, headers, und expires erlaubt sind:

a2enmod rewrite

a2enmod headers

a2enmod expires

/etc/init.d/apache2 restart


2 Mit tmpfs ein Cacheverzeichnis im Arbeitsspeicher erstellen

Standartmäßig wird Boost Dateien im cache Verzeichnis Ihres Dokumentpfads cachen (z.B. in meinem Fall /var/www/www.example.com/web/cache). Es macht jedoch Sinn, gecachete Dateien im Arbeitsspeicher zu speichern, um Ihre Seite zu beschleunigen, da Apache dann nicht mehr auf die Festplatte zugreifen muss. Man kann das tmpfs Dateisystem benutzen, um eine cache Partition im Arbeitsspeicher zu erstellen (siehe Storing Files/Directories In Memory With tmpfs).

Als erstes erstellen wir erneut das cache Verzeichnis:

rm -fr /var/www/www.example.com/web/cache

mkdir /var/www/www.example.com/web/cache

Dann fügen wir die folgende Zeile zu /etc/fstab hinzu:

vi /etc/fstab


[...]
tmpfs /var/www/www.example.com/web/cache tmpfs size=256M,mode=0777 0 0
size=256M bedeutet, dass die Partition eine Größe von 256 MB besitzt. Dies sollte für die meisten Seiten ausreichend sein - für sehr große Seiten müssen  sie die Größe eventuell vergrößern, für kleine Seiten können Sie meist sehr viel weniger Speicherplatz benutzen. Stellen Sie sicher, dass Ihr System genug Speicher für die spezifizierte Größe übrig hat!
Nun remounten Sie alle Partitionen:

mount -a

Sie sollten Ihre Cache Partition nun in der Ausgabe von mount und df -h sehen:

mount

root@server1:/var/www/www.example.com/web# mount

/dev/sda1 on / type ext3 (rw,errors=remount-ro)

tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)

proc on /proc type proc (rw,noexec,nosuid,nodev)

sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)

udev on /dev type tmpfs (rw,mode=0755)

tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)

devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)

tmpfs on /var/www/www.example.com/web/cache type tmpfs
(rw,size=256M,mode=0777)

root@server1:/var/www/www.example.com/web#

df -h

root@server1:/var/www/www.example.com/web# df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/sda1              29G  1.1G   27G   4% /

tmpfs                 502M     0  502M   0% /lib/init/rw

udev                  497M  100K  497M   1% /dev

tmpfs                 502M     0  502M   0% /dev/shm

tmpfs                 256M     0  256M   0% /var/www/www.example.com/web/cache

root@server1:/var/www/www.example.com/web#

Arbeiten Sie auf einer virtuellen Maschine von OpenVZ, wo es kein /etc/fstab gibt, können Sie die folgende Zeile zu /etc/rc.local hinzufügen, sodass sie auch hier ein Cacheverzeichnis im Arbeitsspeicher haben können:

vi /etc/rc.local


[...]
/bin/mount -t tmpfs -o size=256M,mode=0777 tmpfs /var/www/www.example.com/web/cache [...]
Dies wird die Partition bei jedem Systemstart mounten. Um sie gleich zu mounten, ohne dass Sie das System neustarten müssen, benutzen Sie:

mount -t tmpfs -o size=256M,mode=0777 tmpfs
/var/www/www.example.com/web/cache


3 Installation und Konfiguration von Boost

Loggen Sie sich als Admin in die Modules Sektion von Drupal ein (http://www.example.com/admin/modules/install). Tragen Sie http://ftp.drupal.org/files/projects/boost-7.x-1.x-dev.tar.gz in das Install from a URL Feld ein und klicken Sie auf den Install Button (Sie können die aktuelle Boostversion für Drupal 7 unter http://drupal.org/project/boost finden, zur Zeit dieses Tutorials gab es dort nur das boost-7.x-1.x-dev.tar.gz Paket):


Nach der erfolgreichen Installation sehen Sie folgenden Bildschirm. Klicken Sie auf den Enable newly added modules Link um Boost zu aktivieren:


Dadurch kommen Sie zur Liste der Module (http://www.example.com/admin/modules). Scrollen Sie zum Boost Modul, aktivieren Sie die Checkbos und klicken Sie auf Save configuration:


Danach sollten Sie einen Configure Link hinter dem Boost Modul finden. Klicken Sie auf diesen Link um die Boost Konfiguration zu starten:


In der Boost Konfiguration (http://www.example.com/admin/config/system/boost) sollten Sie sich im BOOST SETTINGS Reiter wiederfinden. Es ist ok, die Standartwerte zu übernehmen - klicken Sie auf Save configuration:



Gehen Sie nun zum CACHE EXPIRATION Reiter. Auch hier sollten die Standarteinstellungen in Ordnung sein, klicken Sie deshalb erneut auf Save configuration:


Gehen Sie als nächstes zum FILE SYSTEM Reiter. Überprüfen Sie, ob cache im Root cache directory Feld eingetragen ist (dies sollte der Standartwert sein) - dies übersezt in Ihr Cacheverzeichnis /var/www/www.example.com/web/cache. Die anderen Standartwerte sind ebenfalls in Ordnung, klicken Sie deshalb auf Save configuration:


Öffnen Sie letztendlich den .HTACCESS Reiter - hier können Sie Apache rewrite Regeln spezifizieren, welche Apache mitteilen, im /var/www/www.example.com/web/cache Verzeichnis nach einer gecacheten Kopie der angeforderten Datei zu suchen (nur für anonme Benutzer, angemeldete Benutzer werden immer eine frische Kopie erhalten).  Die Standartwerte sollten erneut in Ordnung sein, klicken Sie deshalb auf Save configuration:




Klicken Sie jetzt auf den .htaccess Generation Button und Sie sollten die Apache rewrite Regeln sehen, welche Sie zu Ihrer .htaccess Datei hinzufügen müssen (/var/www/www.example.com/web/.htaccess):


Dies sind die rewrite Regeln, welche Boost in meinem Fall generiert hat:

### BOOST START ###

# Allow for alt paths to be set via htaccess rules; allows for cached variants (future mobile support)

RewriteRule .* - [E=boostpath:normal]

# Caching for anonymous users

# Skip boost IF not get request OR uri has wrong dir OR cookie is set OR request came from this server OR https request

RewriteCond %{REQUEST_METHOD} !^(GET|HEAD)$ [OR]

RewriteCond %{REQUEST_URI} (^/(admin|cache|misc|modules|sites|system|openid|themes|node/add|comment/reply))|(/(edit|user|user/(login|password|register))$) [OR]

RewriteCond %{HTTPS} on [OR]

RewriteCond %{HTTP_COOKIE} DRUPAL_UID

RewriteRule .* - [S=3]

# GZIP

RewriteCond %{HTTP:Accept-encoding} !gzip

RewriteRule .* - [S=1]

RewriteCond %{DOCUMENT_ROOT}/cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html -s

RewriteRule .* cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html [L,T=text/html,E=no-gzip:1]

# NORMAL

RewriteCond %{DOCUMENT_ROOT}/cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html -s

RewriteRule .* cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html [L,T=text/html]

### BOOST END ###

Der interessante Teil ist die RewriteCond %{HTTP_COOKIE} DRUPAL_UID Zeile. Boost erstellt für alle eingeloggten Benutzer einen Cookie namens DRUPAL_UID - wenn dieser Cookie gesetzt ist, wird der Benutzer keinen gecacheten Inhalt  erhalten. Dies stellt sicher, dass nur anonymen Benutzern gecacheter Inhalt angezeigt wird.

Boost teilt Ihnen außerdem mit, wo genau Sie diese in Ihrer .htaccess Datei platzieren müssen:

Copy this into your .htaccess file below

# If your site is running in a VirtualDocumentRoot at http://example.com/,

# uncomment the following line:

# RewriteBase /

and above

# Pass all requests not referring directly to files in the filesystem to

# index.php. Clean URLs are handled in drupal_environment_initialize().


Öffnen Sie Ihre .htaccess Datei:

vi /var/www/www.example.com/web/.htaccess

Als erstes kommentieren Sie die Sektion <IfModule mod_expires.c>...</IfModule> aus um zu verhindern, dass
Browser den Inhalt zusätzlich zum Filecache cachen, da Sie ansonsten die Kontrolle darüber verlieren, was dem Besucher im Endeffekt angezeigt wird. Stattdessen fügen Sie einige Köpfe hinzu, die dem Browser sagen, dass er niemals Inhalt cachen darf:
[...]
##<IfModule mod_expires.c> ## # Enable expirations. ## ExpiresActive On ## ## # Cache all files for 2 weeks after access (A). ## ExpiresDefault A1209600 ## ## <FilesMatch .php$> ## # Do not allow PHP scripts to be cached unless they explicitly send cache ## # headers themselves. Otherwise all scripts would have to overwrite the ## # headers set by mod_expires if they want another caching behavior. This may ## # fail if an error occurs early in the bootstrap process, and it may cause ## # problems if a non-Drupal PHP file is installed in a subdirectory. ## ExpiresActive Off ## </FilesMatch> ##</IfModule> <IfModule mod_headers.c> Header set Expires "Sun, 19 Nov 1978 05:00:00 GMT" Header set Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0" </IfModule> [...]
(Es ist in Ordnung Browser statische Dateien wir Bilder, Javascript, css und ähnliches cachen zu lassen - sehen Sie sich hierzu Make Browsers Cache Static Files With mod_expires On Apache2 (Debian Squeeze) an - Sie sollten jedoch niemals erlauben, HTML zu cachen!)

Weiter unten in der .htaccess Datei gibt es zwei derzeit auskommentierte rewrite Regeln, welche Ihre Besucher entweder zu Ihrer www. geprefixten Seite weiterleitet (z.B. wird example.com zu www.example.com geleitet) oder andersherum (www.example.com wird zu example.com geleitet). Sie sollten eine dieser Regeln anwenden, da Boost sonst zwei Exemplare von jeder gecacheten Seite anlegen wird, eines für www.example.com und eines für example.com, was  Ihren Cache sehr viel ineffektiver macht.
[...]
# If your site can be accessed both with and without the 'www.' prefix, you # can use one of the following settings to redirect users to your preferred # URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option: # # To redirect all users to access the site WITH the 'www.' prefix, # (http://example.com/... will be redirected to http://www.example.com/...) # uncomment the following: RewriteCond %{HTTP_HOST} !^www. [NC] RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301] # # To redirect all users to access the site WITHOUT the 'www.' prefix, # (http://www.example.com/... will be redirected to http://example.com/...) # uncomment the following: # RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC] # RewriteRule ^ http://%1%{REQUEST_URI} [L,R=301] [...]
Letztendlich fügen Sie die Boost rewrite Regeln unter RewriteBase / und über RewriteCond %{REQUEST_FILENAME} !-f ein:
[...]
# Modify the RewriteBase if you are using Drupal in a subdirectory or in a # VirtualDocumentRoot and the rewrite rules are not working properly. # For example if your site is at http://example.com/drupal uncomment and # modify the following line: # RewriteBase /drupal # # If your site is running in a VirtualDocumentRoot at http://example.com/, # uncomment the following line: # RewriteBase / ### BOOST START ### # Allow for alt paths to be set via htaccess rules; allows for cached variants (future mobile support) RewriteRule .* - [E=boostpath:normal] # Caching for anonymous users # Skip boost IF not get request OR uri has wrong dir OR cookie is set OR request came from this server OR https request RewriteCond %{REQUEST_METHOD} !^(GET|HEAD)$ [OR] RewriteCond %{REQUEST_URI} (^/(admin|cache|misc|modules|sites|system|openid|themes|node/add|comment/reply))|(/(edit|user|user/(login|password|register))$) [OR] RewriteCond %{HTTPS} on [OR] RewriteCond %{HTTP_COOKIE} DRUPAL_UID RewriteRule .* - [S=3] # GZIP RewriteCond %{HTTP:Accept-encoding} !gzip RewriteRule .* - [S=1] RewriteCond %{DOCUMENT_ROOT}/cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html -s RewriteRule .* cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html [L,T=text/html,E=no-gzip:1] # NORMAL RewriteCond %{DOCUMENT_ROOT}/cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html -s RewriteRule .* cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html [L,T=text/html] ### BOOST END ### # Pass all requests not referring directly to files in the filesystem to # index.php. Clean URLs are handled in drupal_environment_initialize(). RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !=/favicon.ico RewriteRule ^ index.php [L] [...]
Zum Schluss müssen Sie noch Drupals eigenen Cache unter Home > Administration > Configuration > Development > Performance deaktivieren (denn mit zwei Caches wird es schwer vorherzusehen, was Ihren Besuchern angezeigt wird):


Nun müssen Sie Änderungen in zwei Drupaldateien vornehmen um sicherzustellen, dass Benutzerlogins und Logouts ordentlich mit Boost funktionieren. Öffnen Sie zunächst /var/www/www.example.com/web/modules/user/user.module:

vi
/var/www/www.example.com/web/modules/user/user.module

Fügen Sie in der Funktion user_authenticate($name, $password) die folgenden markierten Zeilen in den Zeilen 2191 - 2193 ein um sicherzustellen, dass der DRUPAL_UID Cookie benutzt wird, sobald sich ein Benutzer einloggt:
[...]
function user_authenticate($name, $password) { $uid = FALSE; if (!empty($name) && !empty($password)) { $account = user_load_by_name($name); if ($account) { // Allow alternate password hashing schemes. require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc'); if (user_check_password($password, $account)) { // Successful authentication. $uid = $account->uid; if ($uid && !isset($_COOKIE['DRUPAL_UID'])) { setcookie('DRUPAL_UID', $uid, $_SERVER['REQUEST_TIME'] + ini_get('session.cookie_lifetime'), ini_get('session.cookie_path'), ini_get('session.cookie_domain')); } // Update user to new password scheme if needed. if (user_needs_new_hash($account)) { user_save($account, array('pass' => $password)); } } } } return $uid; } [...]
Öffnen Sie dann /var/www/www.example.com/web/sites/all/modules/boost/boost.module:

vi
/var/www/www.example.com/web/sites/all/modules/boost/boost.module

Kommentieren Sie in der boost_set_cookie($uid, $expires = NULL) Funktion Zeile 544 aus und fügen Sie Zeile 545 hinzu um sicherzustellen, dass der DRUPAL_UID Cookie gelöscht wird wenn sich ein Benutzer ausloggt:
[...]
function boost_set_cookie($uid, $expires = NULL) { if (!$expires) { $expires = ini_get('session.cookie_lifetime'); $expires = (!empty($expires) && is_numeric($expires)) ? REQUEST_TIME + (int)$expires : 0; setcookie(BOOST_COOKIE, strval($uid), $expires, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure') == '1'); } else { //setcookie(BOOST_COOKIE, '0', $expires, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure') == '1'); setcookie(BOOST_COOKIE, '', $expires, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure') == '1'); } } [...]
Das war's. Das Cacheverzeichnis sollte sich nun füllen, nachdem die ersten anonymen Besucher Ihre Seite besucht haben:

ls -l
/var/www/www.example.com/web/cache/normal/www.example.com/

root@server1:~# ls -l /var/www/www.example.com/web/cache/normal/www.example.com/

total 36

-rw-rw-r-- 1 www-data www-data 11465 Aug 10 11:59 _.html

-rw-rw-r-- 1 www-data www-data  9619 Aug 10 11:59 nginx-413-request-entity-too-large_.html

-rw-rw-r-- 1 www-data www-data  9628 Aug 10 12:00 postfix-mail-loops-back-to-myself_.html

root@server1:~#

Besuchen Sie Ihre Seite als anonymer User und schauen Sie sich den Quelltext an. Auf Seiten, welche aus dem Cache geliefert werden, finden Sie am Ende des Quelltextes den Kommentar <!-- Page cached by Boost -->.


Sie sollten testen, ob sich Benutzer ohne Probleme ein- und ausloggen können. Mit den Änderungen, welche Sie in der user.module und boost.module Datei getätigt haben, sollte dies eigentlich der Fall sein.

Drupals cron wird sich darum kümmern, das Cacheverzeichnis zu leeren, haben Sie Boost beispielsweise gesagt, dass es für eine Stunde cachen soll, werden Cachedateien, welche älter als eine Stunde sind, aus dem Cache gelöscht. Außerdem wird der Cache geleert, wenn Sie eine Seite aktualisieren, um sicherzugehen, dass Ihre Besucher keine alten Inhalte mehr sehen.

Sie können nun ein Werkzeug wie Apache Benchmark (ab) benutzen, um die Leistung Ihrer Seite zu überprüfen - Ihnen sollte auffallen, dass sie nun wesentlich mehr Zugriffe per Sekunde bewältigen kann.

4 nginx als Reverse Proxy hinzufügen

Es ist möglich, Ihre Seite sogar noch schneller zu machen, indem Sie nginx als nicht-cachenden Reverse Proxy zu Ihrem Setup hinzufügen. Wir werden Apache auf Port 8080 laufen lassen und nginx auf Port 80. Da nginx so viel schneller ist als Apache, wenn es darum geht, statische Dateien zu liefern, werden wir es dazu konfigurieren, direkt im Cacheverzeichnis zu überprüfen, ob es eine gecachete Kopie der Anfrage gibt, das heißt wir umgehen Apache (wir werden nginx außer dem auftragen, dies für andere statische Inhalte außerhalb des Cacheverzeichnisses zu tun, sowie Bilder, Javascript und css). Gibt es keine Kopie, wird die Anfrage zu Apache weitergegeben. Anfragen von eingeloggten Benutzern sowie POST-Anfragen werden ebenfalls an Apache weitergegeben und nicht aus dem Cache geliefert.

Als erstes installieren Sie nginx und das mod-rpaf Modul für Apache (dieses Modul lässt Apache die richtigen IPs der Benutzer anzeigen, nicht die IP des nginx Proxys - 127.0.0.1 - i.e., es nimmt die letzte IP des 'X-Forwarded-For' Headers):

apt-get install nginx libapache2-mod-rpaf

Als nächstes konfigurieren wir Apache dazu, auf Port 8080 zu hören:

vi /etc/apache2/ports.conf


# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in # /etc/apache2/sites-enabled/000-default # This is also true if you have upgraded from before 2.2.9-3 (i.e. from # Debian etch). See /usr/share/doc/apache2.2-common/NEWS.Debian.gz and # README.Debian.gz NameVirtualHost *:8080 Listen 8080 <IfModule mod_ssl.c> # If you add NameVirtualHost *:443 here, you will also have to change # the VirtualHost statement in /etc/apache2/sites-available/default-ssl # to <VirtualHost *:443> # Server Name Indication for SSL named virtual hosts is currently not # supported by MSIE on Windows XP. Listen 443 </IfModule> <IfModule mod_gnutls.c> Listen 443 </IfModule>
Ändern Sie den Port außerdem in allen Ihren vhosts, zum Beispiel:

vi /etc/apache2/sites-available/www.example.com.vhost


<VirtualHost *:8080>
[...]
Starten Sie dann Apache neu:

/etc/init.d/apache2 restart

Da wir nginx dazu konfigurieren gecachete Dateien direkt zu liefern und dabei Apache zu umgehen, können wir die Boost rewrite Regeln in der  .htaccess Datei löschen oder auskommentieren:

vi /var/www/www.example.com/web/.htaccess


[...]
## ### BOOST START ### ## ## # Allow for alt paths to be set via htaccess rules; allows for cached variants (future mobile support) ## RewriteRule .* - [E=boostpath:normal] ## ## # Caching for anonymous users ## # Skip boost IF not get request OR uri has wrong dir OR cookie is set OR request came from this server OR https request ## RewriteCond %{REQUEST_METHOD} !^(GET|HEAD)$ [OR] ## RewriteCond %{REQUEST_URI} (^/(admin|cache|misc|modules|sites|system|openid|themes|node/add|comment/reply))|(/(edit|user|user/(login|password|register))$) [OR] ## RewriteCond %{HTTPS} on [OR] ## RewriteCond %{HTTP_COOKIE} DRUPAL_UID ## RewriteRule .* - [S=3] ## ## # GZIP ## RewriteCond %{HTTP:Accept-encoding} !gzip ## RewriteRule .* - [S=1] ## RewriteCond %{DOCUMENT_ROOT}/cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html -s ## RewriteRule .* cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html [L,T=text/html,E=no-gzip:1] ## ## # NORMAL ## RewriteCond %{DOCUMENT_ROOT}/cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html -s ## RewriteRule .* cache/%{ENV:boostpath}/%{HTTP_HOST}%{REQUEST_URI}_%{QUERY_STRING}.html [L,T=text/html] ## ## ### BOOST END ### [...]
Nun erstellen wir ein Backup der original nginx vhost Konfiguration und erstellen wie folgt eine neue:

cp /etc/nginx/sites-available/default
/etc/nginx/sites-available/default_orig

cat /dev/null > /etc/nginx/sites-available/default

vi /etc/nginx/sites-available/default
server {
listen 80; # fill in the correct domain server_name www.example.com; # fill in the correct document root root /var/www/www.example.com/web; client_body_buffer_size 1m; proxy_buffering on; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; # Avoid image hotlinking from other sites and allow browsers to cache location ~* .(js|css|jpg|jpeg|gif|png|svg|ico)$ { valid_referers www.example.com blocked none ; if ($invalid_referer) { return 403; break; } if (-f $request_filename) { expires 30d; add_header Cache-Control public; break; } } # Make sure files with the following extensions do not get loaded by nginx because nginx would display the source code, and these files can contain PASSWORDS! location ~* .(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(.php)?|xtmpl)$|^(..*|Entries.*|Repository|Root|Tag|Template)$|.php_ { deny all; } # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac). location ~ /. { deny all; access_log off; log_not_found off; } # Pass on all PHP requests to the Apache backend location ~* .php$ { proxy_pass http://localhost:8080; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location / { try_files $uri @cache; } location @cache { if ($query_string ~ ".+") { return 405; } # pass requests from logged-in users to Apache if ($http_cookie ~ "DRUPAL_UID" ) { return 405; } # pass POST requests to Apache if ($request_method !~ ^(GET|HEAD)$ ) { return 405; } error_page 405 = @drupal; # do not allow browsers to cache HTML add_header Expires "Sun, 19 Nov 1978 05:00:00 GMT"; add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"; # serve requested content from the cache if available, otherwise pass the request to Apache try_files /cache/normal/$host/${uri}_.html /cache/perm/$host/${uri}_.css /cache/perm/$host/${uri}_.js /cache/$host/0$uri.html /cache/$host/0${uri}/index.html @drupal; } # This sends the php to Apache, running on port 8080 location @drupal { proxy_pass http://localhost:8080; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } error_page 404 = index.php; # redirect server error pages to the static page /50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
Ich habe Kommentare zur Datei hinzugefügt, damit klar wird, was sie bewirkt. Ein Teil auf den Sie achten sollten ist dieser hier:

# Make sure files with the following extensions do not get loaded by nginx because nginx would display the source code, and these files can contain PASSWORDS!

location ~* .(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(.php)?|xtmpl)$|^(..*|Entries.*|Repository|Root|Tag|Template)$|.php_ {

deny all;

}

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).

location ~ /. {

deny all;

access_log off;

log_not_found off;

}

Da nginx Apache bei statischen Dateien übergeht, müssen wir ihm verbieten Dateien mit bestimmen Endungen zu liefern (sowie Konfigurationen und Passwörter) - ansonsten würde der Besucher den Quelltext im Browser sehen. Dies tun wir mit den obigen Zeilen. Sollte ein Besucher beispielsweise versuchen eine Datei mit der Endung .inc zu laden (sowie www.example.com/include /common.inc), wird er einen 403 Forbidden Fehler sehen:


Ich habe die Liste der verbotenen Dateien aus Drupals .htaccess Datei genommen und einige Endungen hinzugefügt.

Zum Schluss ändern wir /etc/nginx/nginx.conf...

vi /etc/nginx/nginx.conf

... und konfigurieren gzip Kompression (siehe How To Save Traffic With nginx's HttpGzipModule (Debian Squeeze)); möglicherweise wollen Sie auch die worker_processes, worker_connections und keepalive_timeout Einstellungen anpassen (siehe http://wiki.nginx.org/DirectiveIndex für eine Erläuterung):
user www-data;
worker_processes 4; error_log /var/log/nginx/error.log; pid /var/run/nginx.pid; events { worker_connections 1024; # multi_accept on; } http { include /etc/nginx/mime.types; access_log /var/log/nginx/access.log; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 2; tcp_nodelay on; # Enable gzip compression, see http://www.howtoforge.com/how-to-save-traffic-with-nginxs-httpgzipmodule-debian-squeeze gzip on; gzip_http_version 1.1; gzip_vary on; gzip_comp_level 6; gzip_proxied any; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js; gzip_buffers 16 8k; gzip_disable "MSIE [1-6].(?!.*SV1)"; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } [...]
Jetzt können Sie nginx starten:

/etc/init.d/nginx start

Testen Sie nun erneut, und sie sollten sehen können, dass anonyme Benutzer gecachete Seiten von nginx geliefert bekommen. Es sollte Ihnen ebenfalls ein wenig schneller vorkommen als ohne nginx. Benutzen Sie Apache Benchmark (ab) um die Leistung Ihrer Seite einzusehen, sollten Sie sehen können, dass sie dank nginx sogar deutlich schneller ist als zuvor.

5 Links

0 Kommentar(e)

Zum Posten von Kommentaren bitte