Bearing all this in mind, we can now set up the Config file neatly. In line with convention, we rename .../cgi-bin to .../perl. We can then put most of the Perl stuff neatly in a <Location> block:
User webuser Group webuser ServerName www.butterthlies.com DocumentRoot /usr/www/APACHE3/APACHE3/site.mod_perl/mod_cgi/htdocs TransferLog /usr/www/APACHE3/APACHE3/site.mod_perl/logs/access_log ErrorLog /usr/www/APACHE3/APACHE3/site.mod_perl/logs/error_log #change this before production! LogLevel debug AliasMatch /perl(.*) /usr/www/APACHE3/APACHE3/site.mod_perl/perl/$1 Alias /perl /usr/www/APACHE3/APACHE3/site.mod_perl/perl DirectoryIndex /perl/home PerlTaintCheck On PerlWarn On <Location /perl> SetHandler perl-script PerlHandler Apache::Registry #PerlHandler Apache::PerlRun Options ExecCGI PerlSendHeader On </Location>
Remember to reduce the Debug level before using this in earnest! Note that the two directives:
PerlTaintCheck On PerlWarn On
won't go into the <Location> block because they are executed when Perl loads.
A quick web site is well on the way to being a good web site. It is probably worth taking a little trouble to speed up your scripts; but bear in mind that most elapsed time on the Web is spent by clients looking at their browser screens, trying to work out what they're about.
We discuss the larger problems of speeding up whole sites in Chapter 12. Here we offer a few tips on making scripts run faster in less space. The faster they run, the more clients you can serve in sequence; the less space they run in, the more copies you can run and the more clients you can serve simultaneously. However, if your site attracts so many people it is still bogging down, you can surely afford to throw more hardware at it. If you can't, why are you bothering?
Users of FreeBSD might like to look at http://www.freebsd.org/cgi/man.cgi?query=tuning for some basic suggestions
The search for perfect optimization can get into subtle and time-consuming byways that are very dependent on the details of how your scripts work. A good reason not to spend too much time on optimizing your code is that the small change you make tomorrow to fix a maintenance problem will probably throw the hard-won optimizations all out of whack.
The whole point of using mod_perl is to get more business out of your server. Just installing it and configuring it as show earlier will help, but there is more you can do.
When mod_perl starts, it has to load the modules used by your scripts:
... use strict; use DBI( ); use CGI; ...
In the normal way of Perl, as modules are called by scripts, they are compiled — Perl scans them for errors and puts them into executable format. This process is faster if it is done at startup and particularly affects the big CGI module. It can be done in advance by including the compile command:
... use strict; use DBI( ); use CGI; CGI->compile(<tags>); ...
You would replace <tags> by a list of the CGI subroutines you actually use.
If you use a database, your scripts will be constantly opening and closing access handles. This process wastes time and can be improved by Apache::DBI.
It is worth turning off KeepAlive (see Chapter 3) on busy sites because it keeps the server connected to each client for a minimum time even if they are doing nothing. This consumes processes, which consumes memory. Because each connection corresponds to a process, and each process has a whole instance of Perl and all the cached compiled code and persistent variables, this can be a great deal of memory — far more than you get with more ordinary Apache usage. Likewise, tuning MaxClients to avoid swapping can improve the performance even though, paradoxically, it actually causes people to have to wait.
The classic tool for making programs run faster is the profiler. It counts clock ticks as each line of code is executed by the processor. The total count for each line shows the time it took. The output is a log file that can be sorted by a presentation package to show up the lines that take most time to execute. Very often problems are revealed that you can't do much about: processing has to be done, and it just takes time. However, occasionally the profiler shows you that the problem is caused by some subroutine being called unnecessarily often. You cut it out of the loop or reorganize the loop to work more efficiently, and your script leaps satisfyingly forward.
A Perl profiler, DProf, is available from CPAN (see http://search.cpan.org).There are two ways of using it (see the documentation). The better way is to put the following line in your Config file:
... PerlModule Apache::DProf ...
This pulls in the profiler and creates a directory below <ServerRoot> called dprof/$$. In there you will find a file called tmon.out, which contains the results. You can study it by running the script dprofpp, which comes with the package.
Interesting as the results of a profiler are, it is not worth spending too much effort on them. If a part of the code accounts for 50% of the execution time (which is most unlikely), getting rid of it altogether will only double the speed of execution. Much more likely that a part of the code accounts for 10% of the time — and getting rid of it (supposing you can) will speed up execution by 10% — which no one will notice.
Copyright © 2003 O'Reilly & Associates. All rights reserved.