views:

285

answers:

1

I would like to set up Apache 2 as a reverse proxy using name-based virtual hosts to decide how requests are routed to back-end servers. Simple enough.

The catch is that these back-end servers may be added and removed in a dynamic fashion. My first idea was to programmatically re-write an Apache configuration file and call apachectl graceful every time a back-end server goes up or down. This does not seem like the correct solution. What is a better way to accomplish this?

I need to be able to gracefully transfer handling of names over to different back-end servers. For instance, Backend-Server-A might be handling requests for example.com. A monitoring process might decide that Backend-Server-A is stale (too much memory usage, there's new version of the server code to handle example.com, etc). The monitoring process starts Backend-Server-B which will soon handle requests for example.com. Apache should direct any new requests for example.com to Backend-Server-B, but allow any pending requests currently being handled by Backend-Server-A to complete before Backend-Server-A is shut down.

Update: Posted to Server Fault

A: 

The only thing that comes to mind is to use a RewriteMap script which will decide which machine to go to, via the P flag to RewriteRule, something like

#!/usr/bin/perl
#This is /usr/bin/requestdistributor.pl
$| = 1; # Turn off buffering
while (<STDIN>) {
        print distributeRequest($_);
}
sub distributeRequest {
    my $request = shift;
    #do whatever you have to do to find the proper machine for the request,
    #return the complete URL with a trailing newline
}

Then in the Apache configuration file

RewriteMap distributeRequests prg:/usr/bin/requestdistributor.pl 
RewriteRule (.*) ${distributeRequests:$1} [P]

#Setup the reverse proxying for all machines, use the proper URLs
ProxyPassReverse / http://machine1
ProxyPassReverse / http://machine2
#and so on...
ProxyPassReverse / http://machineN

Caveats: This might have some flaws as it's untested, you would have to add a new ProxyPassReverse when you add a new server (and do a graceful), and, now that I think about it, depending on the specifics of the applications you might not even need the ProxyPassReverse lines. So, test this and please tell us if it worked (or not).

Vinko Vrsalovic