Apache 2 performance boost with varnish & YSlow

I am writing this post as part of Tero Karvinen’s course: Linux palvelimena (roughly translated: Linux as a server) http://terokarvinen.com/2012/aikataulu-linux-palvelimena-ict4tn003-4-ja-ict4tn003-6-syksylla-2012.

I am using 32-bit Xubuntu 12.10 (Quantal Quetzal) Daily Build October 9th live-environment.

On this post I will attempt to go through the following:

  • Test apache2’s performance before installing varnish
  • Test apache2’s performance after installing varnish
  • Examine the results
  • Check website rankings with YSlow
  • Fix websites with YSlow’s suggestions

I started by installing apache2, MySQL and getting wordpress working (https://kontsu.wordpress.com/2012/10/03/installing-wordpress-under-apache-2/)

with the exeption of not using phpMyAdmin to create the database and the user. I am using MySQL instead.

Creating the database for wordpress without phpMyAdmin

After installing MySQL and testing that it works, I logged in with root.

$ mysql -u root -p

I added a new database for wordpress.

mysql> create database samuelwp;

(you can see all of the databases with ‘show databases;’)

I created a new user for the new database with the same name and an unique password.

mysql> grant all on samuelwp.* to samuelwp@localhost identified by 'al@#hioBalTokmC@zjKger@k';

I exited (‘exit’) and logged in with the user “samuelwp”

$ mysql -u samuelwp -p

I tested my permissions by trying to create a new database

mysql> create database foo;
ERROR 1044 (42000): Access denied for user 'samuelwp'@'localhost' to database 'foo'

Since I didn’t use phpMyAdmin, I had to install MySQL extension to php which is required by WordPress.

$ sudo apt-get install php5-mysql

so far so good. I’m Skipping ahead to the point when wordpress is installed and tested. (no new themes, plugins or permalinks)

Test without varnish

I made the tests by using apache2’s ab (HTTP server benchmarking tool)

$ ab -n 1000 http://localhost/~xubuntu/wp/wordpress/

This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Apache/2.2.22
Server Hostname:        localhost
Server Port:            80

Document Path:          /~xubuntu/wp/wordpress/
Document Length:        9856 bytes

Concurrency Level:      1
Time taken for tests:   107.717 seconds
Complete requests:      1000
Failed requests:        889
   (Connect: 0, Receive: 0, Length: 889, Exceptions: 0)
Write errors:           0
Total transferred:      10120904 bytes
HTML transferred:       9853904 bytes
Requests per second:    9.28 [#/sec] (mean)
Time per request:       107.717 [ms] (mean)
Time per request:       107.717 [ms] (mean, across all concurrent requests)
Transfer rate:          91.76 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:    94  108   7.6    107     133
Waiting:       90  102   7.2    102     124
Total:         94  108   7.6    107     133

Percentage of the requests served within a certain time (ms)
  50%    107
  66%    111
  75%    113
  80%    115
  90%    118
  95%    121
  98%    124
  99%    126
 100%    133 (longest request)

The most interesting lines are 28 and 29 which state that most of the connections failed to load. I will try to fix this with Varnish (web application accelerator. Also known as a caching HTTP reverse proxy.) (https://www.varnish-cache.org/)

Installing & configuring varnish

I installed varnish

$ sudo apt-get install varnish

The connections will be routed from varnish to apache so I made some changes to the ports

$ sudoedit /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>

on the lines 08 and 09 I changed the value from 80 to 8080.

Next I put varnish to listen the port 80

$ sudoedit /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.
#
# Note: If systemd is installed, this file is obsolete and ignored.  You will
# need to copy /lib/systemd/system/varnish.service to /etc/systemd/system/ and
# edit that file.

# Should we start varnishd at boot?  Set to "no" to disable.
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)

# 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 /etc/varnish/secret \
# 	     -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 :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m"


## 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}"
#


## Alternative 4, Do It Yourself
#
# DAEMON_OPTS=""

on the line 046 I changed the value from 6081 to 80.

Test with varnish

$ ab -n 1000 http://localhost/~xubuntu/wp/wordpress/

This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Apache/2.2.22
Server Hostname:        localhost
Server Port:            80

Document Path:          /~xubuntu/wp/wordpress/
Document Length:        9853 bytes

Concurrency Level:      1
Time taken for tests:   0.434 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      10177990 bytes
HTML transferred:       9853000 bytes
Requests per second:    2303.39 [#/sec] (mean)
Time per request:       0.434 [ms] (mean)
Time per request:       0.434 [ms] (mean, across all concurrent requests)
Transfer rate:          22894.40 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:     0    0   4.3      0     136
Waiting:        0    0   4.3      0     136
Total:          0    0   4.3      0     136

Percentage of the requests served within a certain time (ms)
  50%      0
  66%      0
  75%      0
  80%      0
  90%      0
  95%      0
  98%      0
  99%      0
 100%    136 (longest request)

A picture comparing the results of the test:

Now that varnish is enabled there were 0 failed requests and the speed in which the test was completed was over 200 times faster. Instead of having 9 connections in 1 second there were 2303.

Testing websites with YSlow

Yslow is an extension of Firefox which can be downloaded from tools -> add-ons. Yslow needs Firebug extension to work so install it before installing YSlow.

After I had installed both extensions I tested YSlow on the wordpress website I had created.

I got a grade C. The “errors”/notices I received:

  • Use a content delivery network
  • Add Expires headers
  • Configure entity tags
  • Avoid URL redirects>

(I could raise the grade to B. By clicking “Add as CDS -button” on everything possible in the content delivery network tab.)

I got even more notices when checking my (this) blog at wordpress.com. I don’t belive that there is much I can do to make the grade better.

By testing the index.php test page I got a grade A. With only the following notice: “Add Expires headers”.

I couldn’t come up with any real fixes I could do with the websites I tested so I concluded my homework here.

Advertisements

2 thoughts on “Apache 2 performance boost with varnish & YSlow

  1. Pingback: Hello Puppet features | Samuel Kontiomaa

  2. Pingback: Harjoitus 7: (Web-) Palvelimen suorituskyky | lehtonenkari

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s