MySQL and Perl for the Web: Chapter 3 Section 2 (5/5)
[previous] |
Improving Performance with mod_perl
With the preceding discussion in mind, let's look at an example startup file. Suppose you want to give your scripts access to Perl library files in the /usr/local/apache/lib/perl
and /var/lib/perl
directories without having to put use lib
statements for those directories in every single script. Suppose also that most of your scripts use the CGI.pm and DBI modules, so you want to preload them. You can accomplish these goals by writing your startup file as follows:
use strict;
use lib qw(/usr/local/apache/lib/perl);
use lib qw(/var/lib/perl);
use CGI ();
CGI->compile (':all');
use DBI ();
use DBD::mysql ();
1; # return true
Here are some things to note about this startup file, because they aren't particularly obvious:
You might not actually need to include the
use lib
line for thelib/perl
directory. Recent versions ofmod_perl
search that directory automatically.The
()
after the names of the modules that are preloaded prevents method names from being imported. This saves a little memory during Apache startup, and importing the names can wait until your scripts execute.The call to
CGI->compile()
forces preloading of the CGI.pm methods that otherwise are autoloaded on demand. Without this call, these methods won't be loaded until later, and the code will go into the unshared address space of individualhttpd
children.Normally DBI locates and loads the
DBD::mysql
driver when you're using the DBI module to access MySQL. But that doesn't happen until later, when you actually attempt to connect to the MySQL server. To get the advantage of preloading for the driver and not just the main DBI module, you have to load the driver explicitly at startup time.The final line is required; don't leave it out. When Perl reads the startup file, it expects a return value of true or false to indicate whether the file executed successfully. The final line evaluates to 1 (true), which becomes the return value. If you omit the line, Apache startup fails after writing a line like this to the error log:
[error] conf/startup.pl did not return a true value
You must restart Apache each time you modify the startup file, just as when you modify httpd.conf
. However, there's a slight complication in that the startup file won't be read under certain circumstances. If mod_perl
is loaded as a DSO, it's torn down completely and reloaded from scratch whenever Apache restarts. In this case, you don't have anything to worry about; the startup file will be reread when mod_perl
is reinitialized. On the other hand, if mod_perl
is compiled in to httpd
, Apache doesn't reread the startup file by default. You have a couple of options here. First, you can restart with apachectl stop
followed by apachectl start
. That brings the server all the way down and starts a new one, causing the entire initialization sequence to be performed. Alternatively, you can add the following directive to httpd.conf:
PerlFreshRestart on
PerlFreshRestart on
explicitly tells Apache to reread the mod_perl
startup file when it restarts, even for apachectl restart
and apachectl graceful
. However, the mod_perl
Guide cautions that PerlFreshRestart
can cause problems on some systems. Before deciding whether to use it, read the section in the Guide titled "Evil Things Might Happen When Using PerlFreshRestart
." If you decide against it, you'll need to go the route of using apachectl stop
and apachectl start
to restart the server after startup file changes.
After restarting Apache, you can check whether it reloaded the startup file by requesting the perl-status
page described in the section "Test Your mod_perl
Configuration." If you change the Perl search path, for example, this should be reflected in the value of the @INC
array at the bottom of the perl-status
"Loaded Modules" page.
Alternatives to the Startup File
Some of the work that you do in the mod_perl
startup file can be accomplished directly in httpd.conf
. You can add directories to Perl's search path using a PerlSetEnv
directive in httpd.conf
to set the PERL5LIB
variable. The value can be a single directory pathname or a list of colon-separated path names:
PerlSetEnv PERL5LIB /usr/local/apache/lib/perl:/var/lib/perl
However, this is less efficient than using the startup file because it adds a little overhead for each script run by mod_perl
. When you set the path in the startup file, it's done once and affects all scripts automatically.
You can preload Perl modules using the PerlModule directive. This is equivalent to loading the modules in the startup file. One or more modules can be named:
PerlModule CGI DBI DBD::mysql
[previous] |
Created: July 2, 2001
Revised: July 2, 2001