This article is not related in any way with the others in this series, and it represents only another option instead of having NginX. Varnish is an HTTP accelerator, which serves static content from disk or RAM memory. Unlike Squid or other similar software that was created to be mainly a proxy, Varnish has resolved the problems of having data in the virtual memory, and was created from ground up as an HTTP accelerator. It is also very configurable allowing a multitude of uses.
You will probably ask how is this different from memcached, used in conjunction with nginx. The answer is that they are two completely different systems, varnish is an accelerator while memcached is an in-memory key-value store for small chunks of arbitrary data.
Now let's install a typical LAMP system, that everybody blames as being slow and memory consuming. By simply adding varnish as a buffer in front of it, you will notice not only a more linear memory consumption but also an increase in the speed.
We will start by installing MySQL:
Now bring the example configuration. The path might be different in your case though.
Install apache and enable a few modules:
Slow it down by limiting the max clients in the /etc/apache2/apache2.conf file:
Install PHP and a few extra modules, such as suhosin for increased security and APC, an opcode cache:
Enable the APC engine:
And now Varnish:
Now, before you start the servers, let's adjust Apache and Varnish to work together. First change the default port for your virtual host in apache:
Change from <VirtualHost *:80> into <VirtualHost *:8008> (this is just a preference)
The configuration daemon for Varnish is located in /etc/default/varnish. Here you can pass the startup options:
-f /etc/varnish/default.vcl is the configuration file, and -s malloc,256M means that I allowed Varnish to use 256M of my RAM. Further configurations are very well documented in the comments of this file. For me, setting Varnish to use the disk instead of the virtual memory wasn't too much of an improvement. Of course if you have more memory to spare, you can allow it to use more. -a 80 is the port on which varnish listens, which is the default 80 (we want it in front of Apache), and -T localhost:6082 is the administration panel.
Now let's get to the configuration file (/etc/varnish/default.vcl). This is a very simple use of Varnish which strips the cookies of some static files, like jpg and png, allowing them to be cached. In my case this works best, and it also gives me a header information of what was cached and what not (if you check the headers with something like FireBug). Of course you can find even better configurations available. Having a specific configuration for your platform, like Drupal or WordPress, is not a bad thing either.
acl purge {
"localhost";
"127.0.0.1";
}
sub vcl_recv {
// Strip cookies for static files:
if (req.url ~ "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$") {
unset req.http.Cookie;
return(lookup);
}
// Remove has_js and Google Analytics __* cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", "");
// Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
// Remove empty cookies.
if (req.http.Cookie ~ "^\s*$") {
unset req.http.Cookie;
}
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
purge("req.url ~ " req.url " && req.http.host == " req.http.host);
error 200 "Purged.";
}
}
sub vcl_hash {
if (req.http.Cookie) {
set req.hash += req.http.Cookie;
}
}
sub vcl_fetch {
// Strip cookies for static files:
if (req.url ~ "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$") {
unset beresp.http.set-cookie;
}
// Varnish determined the object was not cacheable
if (!beresp.cacheable) {
set beresp.http.X-Cacheable = "NO:Not Cacheable";
}
// You don't wish to cache content for logged in users
elsif(req.http.Cookie ~"(UserID|_session)") {
set beresp.http.X-Cacheable = "NO:Got Session";
return(pass);
}
// You are respecting the Cache-Control=private header from the backend
elsif ( beresp.http.Cache-Control ~ "private") {
set beresp.http.X-Cacheable = "NO:Cache-Control=private";
return(pass);
}
// You are extending the lifetime of the object artificially
elsif ( beresp.ttl < 1s ) {
set beresp.ttl = 300s;
set beresp.grace = 300s;
set beresp.http.X-Cacheable = "YES:Forced";
}
// Varnish determined the object was cacheable
else {
set beresp.http.X-Cacheable = "YES";
}
return(deliver);
}
You can make sure that it works by checking the headers for: Via - 1.1 Varnish
If you found this useful and you want to contribute, please consider sending a donation (click the button below).
Add new comment