Quantcast
Viewing all articles
Browse latest Browse all 31

Web Server Performance for Drupal and WordPress, Part I

This post discusses methods for improving web server performance for Drupal and WordPress, or really any LAMP setup. First we’ll talk about getting better performance out of Apache, and in later installments we’ll talk about installing a general caching system (Varnish and Pound), and finally some performance improvements specific to Drupal and WordPress.

This assumes you have a basic LAMP server set up to run PHP stuff. You’re running Apache 2.2x, PHP 5.3x, and MySQL 5.x, all installed as-is by your package manager. We’ll use Ubuntu 12.04 server for demonstration.

(Side note: The setup presented here is more commonly seen with the Nginx web server, but we’re going to use Apache because it still dominates the web server market, particularly in the enterprise, and there are plenty of scenarios where Nginx isn’t a particularly wise choice. Before tackling any of this you need to consider your environment and the role of your web server. I might explore a Nginx+PHP-FPM or Apache/Nginx hybrid configuration at a later time.)

Step 1: Install a PHP Opcode Cache

An opcode cache like APC allows your web server to use compiled PHP scripts repeatedly instead of having to reinterpret them over and over again. If you do nothing else, perform this step. You can compile the latest APC version by hand (as of this writing, 3.1.13), or just install it with your package manager, as shown in step 2 below.

$ wget http://pecl.php.net/get/APC
$ apt-get install libpcre3-dev
$ tar -xvzf APC-3.1.13.tgz
$ cd APC-3.1.13
$ ./configure --enable-apc --enable-apc-mmap --with-apxs --with-php-config=/usr/bin/php-config
$ make
$ make test
$ make install

For APC configuration, see Step 3 below.

Step 2: Change how Apache handles connections

Most Linux web servers running Apache 2.2 default to using Apache’s Prefork MPM (multi-processing module). Prefork works fine and offers the greatest compatibility with existing Apache modules, but it consumes a relatively large amount of memory because it spawns many processes that each handle one connection at a time. If you set up your web server using its package manager, Apache is probably using Prefork with the mod_php extension to interpret PHP code.

To reduce the memory footprint, you can adjust Apache to use an alternate method of handling incoming connections. This means replacing the Prefork MPM with the Worker MPM, which can handle multiple connections per process (fewer processes = smaller memory footprint). Since mod_php is considered not to be compatible with the Worker MPM threading system, this also means removing mod_php in favor of an alternative PHP interpreter, namely FastCGI. To make FastCGI more useful and flexible, we’ll also install a new process manager, PHP-FPM.

It’s worth noting that Apache with mod_php is going to be faster for pure PHP — while consuming more memory, particularly under heavier loads — so, again, you should consider the intended role of your web server.

1. Go to /etc/apt/sources.list and uncomment the “multiverse” entries. This allows you to install the mod_fastcgi module.

$ vi /etc/apt/sources.list
$ apt-get update
$ apt-get install apache2-mpm-worker libapache2-mod-fastcgi php5-fpm php5-gd

Add php-apc here if you didn’t previously install it. Installing mpm-worker using the Ubuntu package manager will also automatically remove mod_php, temporarily breaking your PHP web sites.

2. Enable Apache’s FastCGI and Actions modules

$ a2enmod fastcgi actions

3. Tell Apache to send all PHP files to the PHP-FPM process using a Unix socket connection

$ mkdir /var/www/fastcgi
$ chown www-data:www-data /var/www/fastcgi
$ vi /etc/apache2/httpd.conf

Enter the following in httpd.conf:

<IfModule mod_fastcgi.c>
    Alias /php5.fastcgi /var/www/fastcgi/php5.fastcgi
    AddHandler php-script .php
    FastCGIExternalServer /var/www/fastcgi/php5.fastcgi -socket /var/run/php-fpm.sock
    Action php-script /php5.fastcgi virtual

    # Protect your FastCGI directory
    <Directory "/var/www/fastcgi">
       Order allow,deny
       <Files "php5.fastcgi">
          Order deny,allow
       </Files>
    </Directory>
</IfModule>

4. Edit your PHP-FPM configuration (/etc/php5/fpm/pool.d/www.conf):

Change the “listen” line to match the socket you specified in httpd.conf:

listen = 127.0.0.1:9000
; change to this:
listen = /var/run/php-fpm.sock

If you want to see the PHP-FPM status page, you’ll need to create a virtual host for it. First, uncomment these lines in /etc/php5/fpm/pool.d/www.conf:

pm.status_path = /status
ping.path = /ping

Then create a virtual host for it in /etc/apache2/sites-available:

<FilesMatch "^ping|status$">
    SetHandler php-script
</FilesMatch>

Step 3: Configure APC

For starters I used the following settings (/etc/php5/conf.d/apc.ini):

extension=apc.so
apc.mmap_file_mask=/apc.shm.XXXXXX
apc.shm_size=128M
apc.ttl = 3600
apc.user_ttl = 7200
apc.gc_ttl = 3600

Generally I’d use APC in shared memory (apc.mmap_file_mask=/apc.shm.XXXXXX), although the default is anonymous mmapped memory which is going to be equivalent performance-wise. The nice thing about PHP-FPM is that each parent will share a single memory pool among all its child processes, much like Apache Prefork will share its APC cache among all processes.

It may also help to unzip the apc.php status page (/usr/share/doc/php-apc/apc.php.gz) and put it in a secure location where you can see it with a web browser. This page gives you a nice graphical representation of your APC cache and settings.

To get the most out of an opcode cache, you’ll want to do some additional configuration in applications like Drupal and WordPress. We’ll talk about this in Part III of this series.

Step 4: Install Memcached

Memcached can speed up WordPress and Drupal sites by reducing their numerous database queries. To install it:

$ apt-get install php5-memcache memcached php-pear
$ pecl install memcache

Check its configuration file (/etc/php5/conf.d/memcache.ini):

; uncomment the next line to enable the module
extension=memcache.so

[memcache]
memcache.dbpath="/var/lib/memcache"
memcache.hash_strategy="consistent"
memcache.maxreclevel=0
memcache.maxfiles=0
memcache.archivememlim=0
memcache.maxfilesize=0
memcache.maxratio=0

And ensure it’s running:

$ ps aux | grep memcache

As with APC, you’ll want to configure your Drupal and WordPress installations to take advantage of Memcached. We’ll discuss this in Part III.

Step 5: Restart everything

$ service apache2 restart && service php5-fpm restart && service memcached restart

If everything is working correctly, you should have a web server with a smaller memory footprint and functional PHP caching. phpinfo() will show “Server API: FPM/FastCGI” and that APC and Memcache support are enabled. Your apc.php status page will show you graphs and usage statistics for the existing cache.

In our next installments we’ll talk about a general caching system (Varnish and Pound) and some performance improvements specific to Drupal and WordPress.

The post Web Server Performance for Drupal and WordPress, Part I appeared first on GeoffStratton.com.


Viewing all articles
Browse latest Browse all 31

Trending Articles