Varnish and Apache2
One client had some issues with Apache2 and a WordPress site. While WordPress isn’t really a great performer, this client had multiple domains on the same IP and dropping Nginx in didn’t seem like it would make sense to solve the immediate problem.
First things first, we evaluated where the issue was with WordPress and installed db-cache and wp-cache-2. We had tried wp-super-cache but had seen some issues with it in some configurations. Immediately the pageload time dropped from 41 seconds to 11 seconds. Since the machine was running on a quadcore with 4gb ram and was running mostly idle, the only thing left was the 91 page elements being served. Each pageload, even with pipelining still seemed to cause some stress. Two external javascripts and one external flash object caused some delay in rendering the page. The javascripts were actually responsible for holding up the page rendering which made the site seem even slower than it was. We made some minor modifications, but, while apache2 was configured to serve things as best it could, we felt there was still some room for improvement.
While I had tested Varnish in front of Apache2, I knew it would make an impact in this situation due to the number of elements on the page and the fact that apache did a lot of work to serve each request. Varnish and its VCL eliminated a lot of the overhead Apache had and should result in the capacity for roughly 70% better performance. For this installation, we removed the one IP that was in use by the problem domain from Apache and used that for Varnish and ran Varnish on that IP, using 127.0.0.1 port 80 as the backend.
Converting a site that is in production and live is not for the fainthearted, but, here are a few notes.
For Apache you’ll want to add a line like this to make sure your logs show the remote IP rather than the IP of the Varnish server:
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-A gent}i\"" varnishcombined
Modify each of the VirtualHost configs to say:
<VirtualHost 127.0.0.1:80>
and change the line for the logfile to say:
CustomLog /var/log/apache2/domain.com-access.log varnishcombined
Add Listen Directives to prevent Apache from listening to port 80 on the IP address that you want varnish to answer and comment out the default Listen 80:
#Listen 80 Listen 127.0.0.1:80 Listen 66.55.44.33:80
Configuration changes for Varnish:
backend default { .host = "127.0.0.1"; .port = "80"; } sub vcl_recv { if (req.url ~ "\.(jpg|jpeg|gif|png|tiff|tif|svg|swf|ico|mp3|mp4|m4a|ogg|mov|avi|wmv)$") { lookup; } if (req.url ~ "\.(css|js)$") { lookup; } } sub vcl_fetch { if( req.request != "POST" ) { unset obj.http.set-cookie; } set obj.ttl = 600s; set obj.prefetch = -30s; deliver; }
Shut down Apache, Restart Apache, Start Varnish.
tail -f the logfile for Apache for one of the domains that you have moved. Go to the site. Varnish will load everything the first time, but, successive reloads shouldn’t show requests for images, javascript, css. For this client we opted to hold things in cache for 10 minutes (600 seconds).
Overall, the process was rather seamless. Unlike converting a site to Nginx, we are not required to make changes to the rewrite config or worry about setting up a fastcgi server to answer .php requests. Overall, varnish is quite seamless to the end product. Clients will lose the ability to do some things like deny hotlinking, but, Varnish will run almost invisibly to the client. Short of the page loading considerably quicker, the client was not aware we had made any server changes and that is the true measure of success.
June 8th, 2009 at 11:41 am
[…] can also update apache to log the proper IP address, instead of 127.0.0.1 all the time. See this page on how to do […]
June 24th, 2010 at 3:41 pm
Really nice article. One quick question: under the VCL file above there’s you *are* caching posts in varnish for 10 minutes. You’re not worrying expiring posts when there’s a new comment or the post changes?
Sorry if this question seems dumb. I’m new to Varnish.
June 24th, 2010 at 3:53 pm
In this case, yes, we cached everything for 10 minutes. If I recall this particular instance, a client’s wordpress site was linked in a national newspaper article.
WordPress Benchmarks is another post that I used that detailed the WordPress ESI plugin that I wrote, WP Varnish which was written by pkhamre. A current version of W3 Total Cache (not the one I benchmarked) does also support Varnish purging.
If you were going to run a production wordpress site, this post details a decent configuration. I don’t agree that it is the best configuration, but, there are limitations in Varnish that prevent further development on the WordPress ESI plugin.
October 5th, 2011 at 6:45 pm
[…] http://cd34.com/blog/scalability/varnish-and-apache2/ […]