Listing 1 lb_state.pl
#!/usr/bin/perl
#
## Name: lb_state.pl - squid recirect_program
#
## Author: Tom Northcutt
## Synopsis: squid redirect_program that implements load balancing
# with the ability to keep state for backend applications
## Description:
# This version implements static pages, state and round
# robin load balancing. Credit to: Rajeev Kumar (Sys
# Admin V13 n.2) and Jeremy Zawodny for components of
# this script
#
#
# user defined section ###
use strict;
$|=1;
my $debug = 1;
my $logfile = "/var/log/squid/lb_data.log";
my $serverlist = "/usr/local/squid/etc/servers-up.dat";
#get list of servers that are up
my @servers;
open SUD, "< $serverlist";
while ( <SUD> ){
#skip comments, blank lines
s/#.*//;
next if /^(\s)*$/;
#chomp;
push @servers, $_;
}
close SUD;
print @servers;
my $i = 0;
#use to ensure key passed is valid
my %server_name;
foreach my $key (@servers){
chomp $key;
$server_name{"$key"} = $key;
}
##mainloop ####
while (<>) {
$i++;
$i = 0 if ($i > $#servers);
my $line = $_;
my $server = $servers[$i];
if ($debug){
open F, ">> $logfile" or die "Can't open $logfile : $!";
print F "\n[server $server]\n$i $line";
}
##section 1
#check for URLs that should always be directed to a
#specific node (server1)
if ($line =~ /some.cgi/ || $line =~ /MyWebApp/ || \
$line =~ /~joes_home/ || $line =~ /appDirectory/ ){
print $line;
print F "--static goto server1 only \n-> $line" if $debug;
next;
# a different specific node (server3)
}elsif($line =~ /another.cgi/ || $line =~ /otherWebApp/ || \
$line =~ /~toms_home/ || $line =~ /srvDirectory/ ){
$line =~ s/server1/server3/;
print $line;
print F "--static goto server3 only \n-> $line" if $debug;
next;
##section 2
#check for stateful pages
}elsif($line =~ /lbnode/){
#this can be done more elegantly, but I like split
my ($null,$first) = split(/lbnode=/,$line);
my ($second, $null) = split(/&/,$first);
my ($node, $null) = split(/ /,$second);
chomp $node;
chomp $node;
print F "--found a lbnode tag, node = $node\n" if $debug;
my $j = $server_name{"$node"} || "server1";
print F " --node=$node j=$j --\n" if $debug;
$line =~ s[^http://server1.localdomain] [http://$j.localdomain];
print $line;
print F "-> static lbnode node=$node j=$j $line" if $debug;
next;
##section 3
#round robin
}else{
my $k = $server_name{"$server"} || "server1";
chomp $k;
$line =~ s[^http://server1.localdomain] [http://$k.localdomain];
print $line ;
print F "--round robin, server = $k \n-> $line" if $debug;
}
close F if $debug;
}
|