Who's Your Daddy?
June 19, 2000
The Apache web server behaves like Wilt Chamberlain, spawning many children.
It is a single parent, expected to raise enough children to handle the
average load of incoming
HTTP requests. Unlike human babies,
an Apache child is "born" with all the knowledge of its parent.
So, the more know-how, or compiled Perl in this case, we stuff into the
parent server, the more its children know at birth. This can be a good
thing, but it can also be taken too far -- if daddy has a big full head,
then every baby also has a big full head, and with many
babies that can eat up a lot of RAM.
Apache's parent process is created at the time the Apache server is started,
and its httpd.conf configuration file is evaluated. This is our
opportunity to decide what knowledge the parent will pass onto its children.
You may recall a typical set of mod_perl configuration directives placed in
the httpd.conf file of a mod_perl-compiled Apache server:
Alias /cgi-perl/ "/usr/local/apache/cgi-perl/"
<Location /cgi-perl>
SetHandler perl-script
PerlHandler Apache::Registry
Options ExecCGI
PerlSendHeader On
</Location>
Under the above configuration, all scripts in
/usr/local/apache/cgi-perl/ will be handled by mod_perl. As a simple
mod_perl configuration, the Apache parent server will contain the Perl
interpreter, but that's the only knowledge it will have or pass onto its
spawned children. The children themselves will have to compile any Perl
scripts and any modules that those Perl scripts require. It is worth
remembering that a child process will only need to compile its Perl
scripts once during its lifetime -- the first time -- but there may be many
child processes, spawning and dying, and so this may still result in quite a
few compilations of all scripts and modules.
The PerlRequire directive lets us add more knowledge to the Apache
parent server, which will be passed wholly onto its children. The
recommended procedure is to PerlRequire a Perl script, inside which
we will specify which modules and such to build into the parent server:
Alias /cgi-perl/ "/usr/local/apache/cgi-perl/"
PerlRequire /usr/local/apache/cgi-perl/startup.pl
<Location /cgi-perl>
SetHandler perl-script
PerlHandler Apache::Registry
Options ExecCGI
PerlSendHeader On
</Location>
Let's consider a sample startup.pl script, which fills the Apache
parent server with knowledge:
#! /usr/bin/perl
use strict;
use Apache::Registry ();
# pull in the Perl modules and packages we want to compile once,
# each spawned Apache child will inherit this knowledge
use CGI (); CGI->compile(':all');
use DBI ();
use DBD::mysql ();
require "/usr/local/apache/cgi-perl/fastdb.pl";
1;
Our startup.pl is typical for a server which will execute Perl
scripts which perform database queries -- a common scenario. The thinking
is that all of our Perl scripts which run under this mod_perl server will
want the
CGI
module for easy access to environment variables and form
parameters, as well as the database modules DBI and DBD::mysql since we
happen to be using the
MySQL database.
Notice the inclusion of another Perl script, fastdb.pl. In fact,
we'll soon see the value of this script, which we use to optimize database
queries in several fun and fascinating ways.
To summarize, we've seen that it is wise to prepare the Apache parent server
process with certain bits of "knowledge", or Perl code, which will
be compiled only once and passed on to each spawned child process.
The Perl You Need to Know Special: Introduction to mod_perl Part 3
The Perl You Need to Know
More Who's Your Daddy
|