RSS 2.0 Feed
Posted on August 7th, 2010 at 08:31 AM by Corey Ballou

I’m going to outline the process of switching from Apache’s default installation of MPM Prefork to that of MPM Worker. I will also be covering the proper installation of FastCGI (mod_fcgid) to further improve your server performance. This guide is ideally intended for individuals running on low-memory VPS servers as memory consumption will likely be far lower with the Worker MPM because it spawns threads as opposed to forking child processes. If you’re intentionally reading this article, you’re probably aware of the performance benefits gained.

The worker MPM uses multiple child processes with many threads each. Each thread handles one connection at a time. Worker generally is a good choice for high-traffic servers because it has a smaller memory footprint than the prefork MPM.

I would not considering performing this on a production server as it entails taking down Apache in the process.

With all that being said, let’s begin… There are a few dependencies we need to ensure are installed. Let’s go grab those now:

yum install libtool httpd-devel apr-devel apr

For safety purposes, make a backup copy of any virtualhosts and your httpd.conf file:

cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak

If you already have PHP installed on your machine, you’re going to need to disable it:

mv /etc/httpd/conf.d/php.conf /etc/httpd/conf.d/php.conf.disable

Make note of the fact the file /etc/httpd/conf.d/php.conf handles loading the proper MPM module, whether it be prefork or worker. The line we are concerned with is:

LoadModule php5_module modules/libphp5-zts.so

So what we are looking for is to install the module libphp5-zts:

yum search zts

You will most likely find an entry for php-zts, a “Thread-safe PHP interpreter for use with the Apache HTTP Server”. Install this by running the following:

yum install php-zts

Next we are going to need the FastCGI interface module, which you can install by running:

yum install mod_fcgid

This module creates an Apache configuration file in /etc/httpd/conf.d/fcgid.conf. There are some configuration variables you may want to add to this file, it’s up to you:

# The Communication timeout; your new max execution time variable
# The default is 20 seconds if omitted
IPCCommTimeout 60

# Connection timeout: Default value is 3 seconds
IPCConnectTimeout 3

Next, create the file /etc/httpd/conf.d/php-fcgid.conf with the following contents:

<IfModule mod_fcgid.c>
    # Path to directory containing php.ini
    DefaultInitEnv PHPRC=/etc/

    # Number of PHP children that will be launched.
    #DefaultInitEnv PHP_FCGI_CHILDREN 3

    # Maximum requests before a process is stopped and a new one is launched.
    #DefaultInitEnv PHP_FCGI_MAX_REQUESTS 5000

    # Define a new handler "php-fcgi" for ".php" files
    AddHandler php-fcgi .php

    # Add an action binding the new handler to an alias (see below)
    Action php-fcgi /fcgi-bin/phpfcgi

    # Define the MIME-Type for ".php" files
    AddType application/x-httpd-php .php

    # Define alias "/fcgi-bin/" used by the action above.
    # Allows you to run a different command by overriding alias in vhosts
    Alias /fcgi-bin/ /var/www/cgi-bin/

    # Turn on the fcgid-script handler for all files within the alias "/fcgi-bin/"
    <Location /fcgi-bin/>
        SetHandler fcgid-script
        Options +ExecCGI
    </Location>
</IfModule>

The above script is the bread and butter. We first bind PHP scripts to the php-fcgi handler, which in turn has an action assigned to delegate it to the file /var/www/cgi-bin/phpfcgi. The alias is merely a tricky way of allowing you to override the value in a VHOST entry (if, for instance, you wanted to use a different PHP installation later on). The aliased location entry has an option for executing FastCGI.

This file we referenced, /var/www/cgi-bin/phpfcgi, doesn’t actually exist. We want to symbolically link the file to the php-cgi binary. Let’s do that:

ln -s /usr/bin/php-cgi /var/www/cgi-bin/phpfcgi

Whew, almost there… Modify /etc/sysconfig/httpd with your favorite editor; presumably nano, vi, vim, or emacs and uncomment the following line:

#HTTPD=/usr/sbin/httpd.worker

You’re up to the scariest part of the process, restarting your apache server. Use your favorite method:

# service httpd restart
# apachectl graceful
/etc/init.d/httpd restart

If the restart was successful, do a quick double-check of your log files:

tail -f /var/log/httpd/error.log

Hopefully you’ll find lines like the following at the bottom of the log file:

[notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[notice] Apache/2.2.15 (Unix) DAV/2 mod_fcgid/2.3.5 PHP/5.3.2 configured
Categories Apache, PHP
  • HackerNews
  • Reddit
  • Slashdot
  • Facebook
  • LinkedIn
  • del.icio.us
  • Digg
  • StumbleUpon
  • Twitter

Tags , ,
Comments 2 comments

2 Responses

  1. Tom Boutell says:

    You don’t need a threadsafe PHP if you’re running PHP under fastcgi. The point of fastcgi is that it pushes PHP out of the Apache process into a separate process pool so you can use threads for the core work of Apache.

  2. cs says:

    this is lame because the php-zts package doesnt even include mysql support.
    I followed your tut, only to find that I had to start all over since mysql support is essential.
    you forgot to mention this…
    now, I have to compile php from source.

Leave a Reply

Allowable tags
a, abbr, b, blockquote, cite, code, em, i, strike, strong, pre lang, line

* comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.