Recipe 13.4. Deploying Rails with Pound in Front of Mongrel, Lighttpd, and ApacheProblemYou have a cluster of Mongrel processes serving your Rails application, and you want a lightweight, yet powerful software load-balancing solution for directing requests to the cluster. The load balancer also needs to be able to route requests to other web servers you have running, such as Lighttpd and Apache. SolutionFor a lightweight and flexible software load balancing, use Pound. Perl Compatible Regular Expression (PCRE) is one of Pound's prerequisites.This package lets you use advanced regular expressions for matching properties of incoming requests. Let's download, configure, and install PCRE: $ wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/\ > pcre-5.0.tar.gz $ tar xvzf pcre-5.0.tar.gz $ cd pcre--5.0 $ ./configure $ make $ sudo make install Now get and install the latest stable version of Pound with: $ tar xvzf Pound-2.0.9.tgz $ cd Pound-2.0.9 $ ./configure $ make $ sudo make install On a Debian GNU/Linux system, use apt to get and install Pound. (The benefit of using a packaged version is that you get an init script automatically installed on you system.) $ apt-get install pound The number of ways in which you can configure Pound is limitless. What Pound is good at, in addition to load balancing, is allowing a number of different web servers to exist together in the same server environment. The following configuration file sets Pound up to listen on port 80, and forwards various requests to three different backend web servers using service directives. Each directive handles a subset of requests based on matching text patterns in the request. /etc/pound/pound.cfg: User "www-data" Group "www-data" LogLevel 2 Alive 30 ListenHTTP Address 69.12.146.109 Port 80 End # Forward requests for www to Apache Service HeadRequire "Host:.*www.tupleshop.com.*" BackEnd Address 127.0.0.1 Port 8080 End Session Type BASIC TTL 300 End End # Forward requests Quicktime movies to Lighttpd Service URL ".*.mov" BackEnd Address 127.0.0.1 Port 8081 End Session Type BASIC TTL 300 End End # Handle all remaining requests with Mongrel Service # Catch All BackEnd Address 127.0.0.1 Port 9000 End BackEnd Address 127.0.0.1 Port 9001 End Session Type BASIC TTL 300 End End This configuration is set up to pass requests back to Apache (listening on port 8080), Lighttpd (listening on port 8081), and a small Mongrel cluster (listening on ports 9000 and 9001). On some systems, including Debian GNU/Linux, you need to modify the following file (setting startup equal to 1): /etc/default/pound: startup=1 Start Pound using its init.d script. $ sudo /etc/init.d/pound start With Pound up and running, you can test it simply by passing requests to the port it's listening on. If Pound is routing requests to a backend service that is not running or misconfigured, you'll get an HTTP 503 error. In this case, try to access the problem service directly to rule out your Pound configuration as the cause of the problem. DiscussionPound is a very fast and stable software load balancer that can sit out in front of Lighttpd, a pack of Mongrels, or any other web servers waiting to process and respond to requests. Because of the way Pound handles headers, the correct value of request.remote_ip is preserved by the time the request is received by Rails. This is not the case when Pound is configured behind another web server, such as Lighttpd. Keep this in mind when you decide exactly how your servers are organized. Before beginning to set up an even moderately complex deployment configuration, it helps to have a documented plan as to how your services are to interact. For this kind of planning, nothing beats a clearly labeled network diagram, such as Figure 13-2. Figure 13-2. A Rails deployment configuration load balancing with PoundThe Pound configuration file in the solution contains three types of directives: global, listener, and service. The global directives specify the user and group that Pound is to run under. The log level states how much logging we want Pound to send to syslog, if any. Loglevel takes the following values:
The listener directive, ListenHTTP, specifies the IP address and port that Pound is to listen for requests from (you'll want a real address here). The remainder of the configuration file contains service directives that define what backend servers handle different types of requests. The first Service directive states that anything with a Host header containing www.tupleshop.com should be routed to port 8080 of the local host address (127.0.0.1). In this case Apache, running PHP (among other things), is listening on port 8080, waiting to handle whatever requests Pound passes to it. (There's no reason this IP address couldn't be on another physical server, but in this case all three web servers are on the same box.) The next Service directive uses URL ".*.mov" to match requests for QuickTime movie files. For performance reasons, we want Lighttpd to handle these requests. So while a request for http://blog.tupleshop.com would be handled by the Mongrel cluster, a request for http://blog.tupleshop.com/zefrank.mov would never make it to Mongrel and would instead be served by Lighttpd. The location of .mov files on the server is pretty much irrelevant here; they can be anywhere as long as Lighttpd knows where to find them. The final Service directive effectively serves as a catch all because it's the last one in the file and because there is no URL or header matching criteria defined. This is the one doing the actual load balancing for the Mongrel processes. In this case there are two Mongrel processes listening on ports 9000 and 9001, on the local IP address. See Also
|