Caching für Zope/Plone Portale
Note: Return to tutorial view.
Durch den Einsatz eines Cache Proxy Servers, kann die Auslieferung von Zope und Plone Seiten immens beschleunigt werden. Dieses Tutorial zeigt verschiedene Setups mit dem Webserver Nginx, dem Proxy Varnish mit und ohne installiertem CacheFu.
Einleitung
Wie baut man das Setup bestehend aus Webserver, Proxy und Zope am besten?
Da das Setup für mehre verteilte Zope Clients (ZEO) dienen soll, macht ein zentraler Cache Proxy Sinn.
Daher wird folgender Setup empfohlen:
Browser => Varnish => Nginx => Zopeclient1, Zopeclient2...Erläuterung des Setups
Der Browser stellt eine Anfrage an die Website. Diese kommt auf dem Server an dem Port 80 an. Hier wartet der Varnish nur darauf ihn zu verarbeiten. Dieser schaut in seinem Cache nach, ob er diese Anfrage direkt bedienen kann. Wenn nicht, reicht er die Anfrage an den Nginx auf Port 81 weiter.Der Nginx zuständig für das URLRewriting und Loadbalancing, schreibt die URL um und gibt die Anfrage an einen der Zopeclients im Backend weiter. Der Zopeclient bedient die Anfrage und gibt die angeforderten Objekte zurück. Die zurück gelieferten Objekte gehen über den Nginx zurück an den Varnish der diese je nach Konfiguration in seinen Cache für eine bestimmte Zeit aufnimmt.
Bei weiteren Anfragen nach diesen Objekten, wird der Varnish diese selbst aus seinem Cache heraus beantworten können. Dies für dazu das Hunderte oder gar Tausende von Anfragen in der selben Zeit beantwortet werden können, wo es vorher keine 10 Anfragen in der selben Zeit waren.
Vorteile dieses Setups
Da wir den Cache ganz vorne haben wird ein Großer Teil der Anfragen direkt durch den Varnish abgearbeitet und belastet weder den Webserver noch die Zopeclients im Backend. Die Anfragen die nach hinten durch greifen, verteilen die Last auf alle Zopeclients und füllen so den zentralen Cache.
Varnish als Caching Proxy einrichten
Installation und Konfiguration des Caching Proxy Server Varnish.
Varnish installieren
aptitude install varnish
Varnish konfigurieren
Es gibt zwei wichtige Konfigurationsdateien nach der Installation./etc/default/varnish
/etc/varnish/default.vcl
/etc/default/varnish anpassen
cat /etc/default/varnishWir wählen hier die 3. Variante. Folgenden Parametern gilt besondere Aufmerksamkeit.
# Configuration file for varnish
#
# /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK
# to be set from this shell script fragment.
#
# 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)
# This file contains 4 alternatives, please use only one.
## Alternative 1, Minimal configuration, no VCL
#
# Listen on port 6081, administration on localhost:6082, and forward to
# content server on localhost:8080. Use a 1GB fixed-size cache file.
#
# DAEMON_OPTS="-a :6081 \
# -T localhost:6082 \
# -b localhost:8080 \
# -u varnish -g varnish \
# -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"
## Alternative 2, Configuration with VCL
#
# Listen on port 6081, administration on localhost:6082, and forward to
# one content server selected by the vcl file, based on the request. Use a 1GB
# fixed-size cache file.
#
#DAEMON_OPTS="-a :6081 \
# -T localhost:6082 \
# -f /etc/varnish/default.vcl \
# -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"
#
## 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=80
# 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
# 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_STORAGE}"
## Alternative 4, Do It Yourself
#
# DAEMON_OPTS=""
VARNISH_LISTEN_ADDRESS
- das Netzwerkinterface auf dem der Varnish lauschen soll
- default: '' (lauscht auf alle)
VARNISH_LISTEN_PORT
- der Netzwerkport auf dem der Varnish lauschen soll
- default: 6081 (wir wählen hier den Port 80, da dort die Anfragen der Browser ankommen)
VARNISH_STORAGE
- hier kann man als ersten Parameter file oder malloc angeben (also ob der Cache im RAM oder in einer Datei gehalten wird)
- default: file
VARNISH_STORAGE_SIZE
- gibt bei verwendung von file, die Größe des Cachefiles an
- default: 1GB
/etc/varnish/default.vcl anpassen
Hier werden die einstellungen zum Caching vorgenommen. Im folgenden eine Beispiel Konfiguration.cat /etc/varnish/default.vcl
# Das default Backend, zu dem alle Anfragen die der Varnish nicht beantworten kann, durchgereicht werden.
# In unserem Fall lauscht hier der Nginx:
backend default {
.host = "127.0.0.1";
.port = "81";
}
# ACL, für den Zugriff von Zope. Dieser ist nötig damit Zope Objekte aus dem Cache entfernen kann,
# wenn diese veraltet sind. Wir geben hier den Zugriff von lokal und aus dem LAN frei.
acl purge {
"localhost";
"10.1.0.0"/24;
}
sub vcl_recv {
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
pipe;
}
if (req.request != "GET" && req.request != "HEAD") {
/* We only deal with GET and HEAD by default */
# POST - Logins and edits
if (req.request == "POST") {
pass;
}
# PURGE - The CacheFu product can invalidate updated URLs
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
lookup;
}
}
# Don't cache authenticated requests
if (req.http.Authorization || req.http.Cookie && req.http.Cookie ~ "__ac(|_(name|password|persistent))="){
# Force lookup of specific urls unlikely to need protection
if (req.url ~ "\.(js|css)") {
remove req.http.cookie;
lookup;
}
pass;
}
lookup;
}
sub vcl_pipe {
pipe;
}
sub vcl_pass {
pass;
}
sub vcl_hash {
set req.hash += req.url;
if (req.http.host) {
set req.hash += req.http.host;
} else {
set req.hash += server.ip;
}
hash;
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged";
}
deliver;
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache";
}
fetch;
}
sub vcl_fetch {
if (req.request == "PURGE") {
error 404 "Not in cache";
}
set obj.prefetch = -30s;
# hier wird eine min TTL von einer Stunde gesetzt.
# Das heißt alle Objekte die gechached werden können,
# werden mindestens für 1 Stunde im Cache gehalten.
# Über die Einstellungen in Zope kann dieser Wert noch für bestimmte Objekte erhöht werden
if (obj.ttl < 3600s) {
set obj.ttl = 3600s;
}
deliver;
}
sub vcl_deliver {
deliver;
}
Nginx für URLRewriting und Loadbalancing
Der schlanke Webserver Nginx dient uns zum Umschreiben der URL's auf die Zope Struktur und für eine einfache Lastverteilung auf die Zopeclients im Backend.
Nginx installieren
aptitude install nginx
Nginx konfigurieren
Allgemeine Einstellungen
Nach der Installation passen wir zunächst die Datei /etc/nginx/nginx.conf an:# cat /etc/nginx/nginx.confHinzu gefügt wurde hier die folgende Angabe:
user www-data;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
client_max_body_size 150m;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
tcp_nodelay on;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
client_max_body_size 150m;
- diese erhöht die Grenze für Dateiuploads auf 150MB
- default: 1MB
Backends und load balancing
Wir erzeugen die Datei /etc/nginx/conf.d/backends.conf mit folgendem Inhalt:# cat /etc/nginx/conf.d/backends.confHier wird ein Backend namens zope_backend definiert, welches die zwei Zopeclients zclient1.lan und zclient2.lan beinhaltet. Dieses Backend können wir nun im folgenden für das virtualHosting verwenden.
upstream zope_backend {
server zclient1.lan:8080;
server zclient2.lan:8080;
}
virtualHosting (URLRewriting)
Wir erzeugen die Datei /etc/nginx/sites-enabled/zope.confmit folgendem Inhalt:# cat /etc/nginx/sites-enabled/zope.confWir sehen hier einen virtualHost Eintrag für die Domain example.com. Das vorher definierte zope_backend wird hier in der proxy_pass Anweisung verwendet. Die Anfrage wird hier per proxy_pass Anweisung an einen der Zopeclients durch gereicht. Hier befindet sich die Website examle.com in dem Ordner /hosts. Es können in der zope.conf beliebig weitere virtualHost Einträge vorgenommen werden.
server {
listen 81;
server_name example.com www.example.com;
location / {
proxy_pass http://zope_backend/VirtualHostBase/http/example.com:80/hosts/example.com/VirtualHostRoot/;
}
}