Допустим, некий интернет-проект работает на паре независимых серверов у разных провайдеров с разными доменными именами, на одном из которых (медленном - slow) в корне через .htaccess идет редирект на второй (быстрый - fast). [Именно так, к слову, обстоит дело с нашим теннисным клубом где fast - tennismatchmachine.com , а slow - motivation.ru .] Медленный каждые три часа забирает с быстрого снимок БД и заливает у себя. Каким образом, в случае отказа fast-сервера, slow-сервер надежно узнает об этом и отменит редирект? И как, когда потом восстановит его обратно? Решаем задачу:
A. На трех хостах, включая fast, кладем незамысловатый скриптик reply_self:
B. А на slow каждую минутe запускаем нечто вроде :
#!/usr/bin/perl
my $tainted = 0;
my $tested_host = 'tennismatchmachine.com';
$test_host_url = 'http://'.$tested_host.'/scripts/reply_self';
my $first_link_ip = 'onnnemoreee.ru';
my $first_link_test_url = 'http://'.$first_link_ip.'/protected/reply_self';
my $second_link_ip = 'anotttheer.ru';
my $second_link_test_url = 'http://'.$second_link_ip.'/scripts/reply_self';
my $user = 'wget';
my $passwd = 'dumbasspassword';
local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
&Connect(0);
unless ($tainted) {
&Connect(1);
unless ($tainted) {
&Connect(2);
unless ($tainted) {
sleep(30);
&Connect(0);
}
} else {
sleep(30);
&Connect(0);
}
}
if (!(-f './tmm_flag_down') && $tainted && $tainted ne '3') {
system("echo > ./tmm_flag_down");
system("date >> ./tmm_changed");
system("echo 'DOWN' >> ./tmm_changed");
system("echo '==============' >> ./tmm_changed");
system("./if_mail_tmm_changed.sh");
system("/bin/rm -f ./public_html/.htaccess");
system("cd public_html;/bin/ln -s ./.htaccess.home ./.htaccess;cd ..;");
} elsif (-f './tmm_flag_down' && $tainted eq '3') {
system("/bin/rm -f ./tmm_flag_down");
system("date >> ./tmm_changed");
system("echo 'UP' >> ./tmm_changed");
system("echo '==============' >> ./tmm_changed");
system("./if_mail_tmm_changed.sh");
system("/bin/rm -f ./public_html/.htaccess");
system("cd public_html;/bin/ln -s ./.htaccess.tmm ./.htaccess;cd ..;");
}
sub Connect {
my $p = shift;
my $test_url;
if ($p eq '0') {
$test_url = $test_host_url;
} elsif ($p eq '1') {
$test_url = $first_link_test_url;
} elsif ($p eq '2') {
$test_url = $second_link_test_url;
}
my $wget_cmd = 'wget --timeout=5 --http-user '.$user.' --http-passwd '.$passwd.' -O - '.$test_url;
eval {
alarm 5;
system($wget_cmd.' 2>/dev/null 1>/dev/null');
open (IN, '-|', $wget_cmd.' 2>&1')
or die ("Can't wget");
my $r = '';
while (!eof(IN)) {
my $q = readline (*IN);
$q =~ /(\S+)!(\d+\.\d+\.\d+\.\d+)/;
if ($1 && $r ne $1) {
$r = $1;
$tainted = ($1 =~ /^tennismatchmachine/) ? 3 : 4;
last if ($tainted eq '3');
}
}
close (IN);
alarm 0;
};
} #end Connect
Voila!
A. На трех хостах, включая fast, кладем незамысловатый скриптик reply_self:
#!/usr/bin/perl
use CGI;
$query = new CGI;
print $query->header;
my $me=`/bin/hostname`;
$chop($me);
my $addr=$ENV{'REMOTE_ADDR'};
print $me."!";
print $addr."\n";
use CGI;
$query = new CGI;
print $query->header;
my $me=`/bin/hostname`;
$chop($me);
my $addr=$ENV{'REMOTE_ADDR'};
print $me."!";
print $addr."\n";
B. А на slow каждую минутe запускаем нечто вроде :
#!/usr/bin/perl
my $tainted = 0;
my $tested_host = 'tennismatchmachine.com';
$test_host_url = 'http://'.$tested_host.'/scripts/reply_self';
my $first_link_ip = 'onnnemoreee.ru';
my $first_link_test_url = 'http://'.$first_link_ip.'/protected/reply_self';
my $second_link_ip = 'anotttheer.ru';
my $second_link_test_url = 'http://'.$second_link_ip.'/scripts/reply_self';
my $user = 'wget';
my $passwd = 'dumbasspassword';
local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
&Connect(0);
unless ($tainted) {
&Connect(1);
unless ($tainted) {
&Connect(2);
unless ($tainted) {
sleep(30);
&Connect(0);
}
} else {
sleep(30);
&Connect(0);
}
}
if (!(-f './tmm_flag_down') && $tainted && $tainted ne '3') {
system("echo > ./tmm_flag_down");
system("date >> ./tmm_changed");
system("echo 'DOWN' >> ./tmm_changed");
system("echo '==============' >> ./tmm_changed");
system("./if_mail_tmm_changed.sh");
system("/bin/rm -f ./public_html/.htaccess");
system("cd public_html;/bin/ln -s ./.htaccess.home ./.htaccess;cd ..;");
} elsif (-f './tmm_flag_down' && $tainted eq '3') {
system("/bin/rm -f ./tmm_flag_down");
system("date >> ./tmm_changed");
system("echo 'UP' >> ./tmm_changed");
system("echo '==============' >> ./tmm_changed");
system("./if_mail_tmm_changed.sh");
system("/bin/rm -f ./public_html/.htaccess");
system("cd public_html;/bin/ln -s ./.htaccess.tmm ./.htaccess;cd ..;");
}
sub Connect {
my $p = shift;
my $test_url;
if ($p eq '0') {
$test_url = $test_host_url;
} elsif ($p eq '1') {
$test_url = $first_link_test_url;
} elsif ($p eq '2') {
$test_url = $second_link_test_url;
}
my $wget_cmd = 'wget --timeout=5 --http-user '.$user.' --http-passwd '.$passwd.' -O - '.$test_url;
eval {
alarm 5;
system($wget_cmd.' 2>/dev/null 1>/dev/null');
open (IN, '-|', $wget_cmd.' 2>&1')
or die ("Can't wget");
my $r = '';
while (!eof(IN)) {
my $q = readline (*IN);
$q =~ /(\S+)!(\d+\.\d+\.\d+\.\d+)/;
if ($1 && $r ne $1) {
$r = $1;
$tainted = ($1 =~ /^tennismatchmachine/) ? 3 : 4;
last if ($tainted eq '3');
}
}
close (IN);
alarm 0;
};
} #end Connect
Voila!