Configuring a web server

Once you have your application working on the production machine, you're ready to point a real web server at it. Which server you use is usually decided by what your other applications are using. If you already have Apache and mod_perl set up, then use that. If you aren't serving many users, you will probably be fine with just the development server included with Catalyst. If you're tired of Apache, you can use lighttpd with FastCGI. Catalyst tries to make mod_perl, FastCGI, and the development server behave the same, so you should use whatever is convenient for you. (Note that plain CGI is also an option, but it will be unbearably slow, so don't use it.)

Generally, new deployments use Apache and FastCGI, as that configuration is relatively easy to set up and manage. As of writing, this FastCGI is the preferred configuration and unless you have reasons otherwise, you probably should just stick with FastCGI. mod_perl is most useful if you want to write an Apache module integrating Perl code directly into the web server. For applications, FastCGI is simpler to set up and manage in the usual cases.

Apache

Apache is the world's most common web server, so most sites are already using Apache and have a configuration that you can easily add to your Catalyst application. If you decide to use Apache, you can use either mod_perl or FastCGI to actually run your Catalyst application.

FastCGI

FastCGI is easiest of the two to set up; simply install mod_fastcgi (or the newer mod_fcgid, which might be better for some users) and add the following to Apache's httpd.conf file:

FastCgiServer /.../myapp/script/myapp_fastcgi.pl -processes 3
Alias /myapp/ /.../myapp/script/myapp_fastcgi.pl/

Note

Please note that in the last lines of code, the ellipsis (...) is an abbreviation for wherever you want your application code to live. Many sites use /var/www or /var/www-apps, but /home/myapp/ or something similar is also possible.

The Apache configuration may look like the following on a virtual host:

<VirtualHost *:80>
AddHandler fastcgi-script .fcgi
ServerName myapp.com
ServerAlias www.myapp.com
DocumentRoot /mnt/volume/www/myapp/root
FastCgiServer /mnt/volume/www/myapp/script/myapp_fastcgi.pl - processes 1
Alias /static/ /mnt/volume/www/myapp/root/static/
Alias / /mnt/volume/www/myapp/script/myapp_fastcgi.pl/
<Location /mnt/volume/www/myapp/root/static/>
SetHandler default-handler
</Location>
</VirtualHost>

For more details on setting up fastcgi on Apache, you can read http://httpd.apache.org/mod_fcgid/.

This configuration will tell Apache to start (and maintain) three instances of your application, and to make the application available on the web under the /myapp URL. You can put the Alias directive inside a VirtualHost block to make your application available at the root of a virtual host.

If you'd like to run your FastCGI server on a separate machine, you can tell Apache about a FastCGI external server:

FastCgiExternalServer /var/www/htdocs/myapp.fcgi -host remote.server. com:3010
Alias /myapp/ /var/www/htdocs/myapp.fcgi

Note that /var/www/htdocs/myapp.fcgi isn't a real file; it's a virtual file that ends with .fcgi (so Apache knows to invoke the fastcgi-handler) and exists inside the doc root (so Apache knows it's allowed to be served). The -host directive points FastCGI at the server running on remote.server.com, port 3010.

On remote.server.com, you'll want to run scripts/myapp_fastcgi.pl -l :3010 and set up firewall rules so that only your frontend server can talk to port 3010. You can also use another port number, as there is no defined standard port.

If your application is in a PAR, you can start an external FastCGI server by running parl myapp.par myapp_fastcgi.pl -l :3010. You can then configure a remote Apache with FastCGI to support to connect to that server, just as described above for the non-PAR case.

In addition, the external server need not be on another host, it can be run on localhost the same way. You can also use a named socket on the filesystem instead of a host and port; just say -socket instead of -host. It is easier to enforce permissions on files than TCP ports, so if you care about fine-grained access to the FastCGI server, then you might like using the named socket better. Keep in mind that you can't use a named socket when the FastCGI server is running on a different host from the frontend web server.

Static content

One last tweak is to have Apache serve your static content without involving your Catalyst application. All you'll need to do is add an Alias directive like the following:

Alias /myapp/static /.../myapp/root/static

Apache can serve static content much more efficiently than your Catalyst application, so for maximum performance it's best to add this piece of configuration.

mod_perl

For years, mod_perl was the only way to write efficient web applications, so it's still in wide use. Serving your Catalyst application with mod_perl is very easy. First, you'll need Catalyst::Engine::Apache from the CPAN.

Then, to a mod_perl-enabled Apache 2.x.x configuration, you'll just need to add the following lines:

PerlSwitches -I/.../myapp/lib
PerlModule MyApp
<Location /> # or you can use /myapp, or a VirtualHost, etc.
SetHandler modperl
PerlResponseHandler MyApp
</Location>

On Apache 1.3, the setup is slightly different:

<Perl>
use lib qw(/.../myapp/lib);
</Perl> PerlModule MyApp
<Location />
SetHandler perl-script
PerlHandler MyApp
</Location>

Finally, if you're using PAR, you can install Apache::PAR and point Apache at the PAR instead of a directory:

PerlAddVar PARInclude /.../myapp.par
PerlModule Apache::PAR
PerlModule MyApp

These directives replace the<Perl> or PerlSwitches sections (but not the<Location> section).

After you have set up your configuration, you can restart Apache and enjoy your application. The same static caveat with FastCGI applies to mod_perl, so you will want to add an alias or location for serving the static content directly. (This is more difficult with PAR, but you might want to take the slight performance hit for the convenience of one-file deployment. Additionally, you can copy the static content somewhere outside of the PAR file and use only the PAR for code. Then there is no performance hit, but maintenance is slightly more difficult.)

Performance considerations

Unfortunately, the mod_perl setup described in the previous section is not ideal. mod_perl works by loading your entire application into every Apache process. This means that when an Apache process has to spoon-feed a dial-up user a 200M movie (or 20k of HTML, the concept is the same), the memory that your application used is wasted streaming bytes instead of processing requests. On sites with high traffic, this will result in unacceptable performance, as the application processes will be tied up serving data (and you can't start more application processes because you'll be out of memory).

This is a well-known mod_perl problem not specific to Catalyst (or even Perl, mod_ruby, and mod_python suffer the same problem), and is part of the reason why FastCGI is becoming popular.

The solution is to run a two-tiered architecture. In front of your mod_perl application processes, you place a lean load balancer (such as perlbal) or a basic Apache process. The frontend will pass dynamic requests to the backend application servers. When the dynamic result is ready, the dynamic server will send it very quickly to the frontend server. The frontend server will then send the response to the client. While that frontend server is tied up, another lean frontend server can dispatch another dynamic request to your application. This setup ensures that you are always using as much CPU and bandwidth as possible.

Setting up a frontend server is covered in the mod_perl book at http://perl.apache.org/, and perlbal is covered in the next section. The only thing you need to do for Catalyst is to tell it that there's a frontend proxy by setting using_frontend_proxy to 1 in the application config. This option is necessary so that Catalyst will generate URLs that point to the frontend server when you use uri_for and uri_for_action.

If you're going to use mod_perl for a large site, be sure to set up a two-tiered architecture.

Development server and perlbal

The final deployment option is to simply use the myapp_server.pl development server. This server is not intrinsically limited in any way; you can expose it to the Internet and your application will work fine. The main problem is the same as mod_perl, though; feeding the resulting HTML (or images, and so on) back to the client will tie up system memory unnecessarily. Additionally, as the development server can handle only one connection at a time, users will have to wait in line to use your application, which is probably not acceptable unless you are creating something like a desktop web application.

That means it's easy to get a very efficient two-tiered setup going with perlbal. The basic idea is to start a pool of development servers running on different ports, and then have perlbal load balance between them. perlbal will handle talking to clients and will send dynamic requests to a waiting development server. The performance of this setup will be excellent, as perlbal adds almost no overhead (it's used for popular sites such LiveJournal and Vox, and easily handles hundreds of millions of requests a day).

To get started, install perlbal from the CPAN (it's also available at http://www.danga.com/perlbal/). Then, create a simple perlbal configuration file called /etc/perlbal/perlbal.conf that looks like this:

CREATE POOL myapp
POOL myapp ADD 127.0.0.1:3010
POOL myapp ADD 127.0.0.1:3011
POOL myapp ADD 127.0.0.1:3012
POOL myapp ADD 127.0.0.1:3013
CREATE SERVICE balancer
SET listen = 0.0.0.0:80
SET role = reverse_proxy
SET pool = myapp
SET persist_client = on
SET persist_backend = on
ENABLE balancer
# open up a management port for dynamic configuration
CREATE SERVICE mgmt
SET role = management
SET listen = 127.0.0.1:60000
ENABLE mgmt

When that's set up, start a few instances of your application:

$ perl script/myapp_server.pl -p 3010 -d
$ perl script/myapp_server.pl -p 3011 -d
$ perl script/myapp_server.pl -p 3012 -d
$ perl script/myapp_server.pl -p 3013 -d

and start perlbal:

$ perlbal

Now visit http://localhost/, and you should be good to go. If you choose to keep perlbal's management interface up, you should firewall off its port (60000).

Database

Storage and schema deployment, upgrade, and maintenance could be a major challenge if not handled with care. You may want to explore the class DBIx::Class::Schema::Versioned that helps with schema versioning. Refer to

http://search.cpan.org/~ash/DBIx-Class-0.08013/lib/DBIx/Class/Schema/Versioned.pm.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.251.206