DonCullen Posted September 17, 2007 Share Posted September 17, 2007 I have it set up so the address bnls.dementedminds.net will redirect to a live server, and if the server goes down, it'll go through a list in a mysql table seeking the next available live server, and upon finding one, it will modify the DNS zone tables to point to the alternative server, and reload the named service. As hackish as it seems, it apparently works. This is my current solution: The php script is executed via cron every half hour. #!/usr/bin/php <? # Include needed files include 'db.php'; include 'functions.php'; $dmsid = GetInfo("servers", "serveraddress", "bnls.dementedminds.net", "id"); $status = checkserver($dmsid, $forceupdate); $oldtarget = GetInfo("servers", "id", $dmsid, "target"); $sqlquery = 'SELECT id,serveraddress FROM servers ORDER BY id ASC'; $serverarray = mysql_query($sqlquery); while($row = mysql_fetch_array($serverarray)){ $sid = $row['id']; $saddress = $row['serveraddress']; $results = checkserver($sid, $forceupdate); if($sid == $dmsid){ #Demented Minds Redirector if(!$results){ #Crap, the server it's redirecting to is down! FIND ANOTHER SERVER! $foundserver = false; $servers = array("bnls.valhallalegends.com", "valhallalegends.com", "jbls.org", "hdx.jbls.org"); foreach ($servers as $newtarget){ if(testServer($newtarget, "9367")){ # Alternate Target Server is online! #Point to new target $codetoexec = 'sudo /code/./updatebnls.sf '.$oldtarget.' '.$newtarget.' 2>&1'; exec($codetoexec, $output); #Update database with new target WriteInfo('servers', 'id', $dmsid, 'target', $newtarget); WriteInfo('servers', 'id', $dmsid, 'status', 'online'); break; #Found new server, don't need to keep looking for alternates } else { # Damn, the server we tested is down, TEST AGAIN! if(testServer($newtarget, "9367")){ # Alternate Target Server is online! #Point to new target $codetoexec = 'sudo /code/./updatebnls.sf '.$oldtarget.' '.$newtarget.' 2>&1'; exec($codetoexec, $output); #Update database with new target WriteInfo('servers', 'id', $dmsid, 'target', $newtarget); WriteInfo('servers', 'id', $dmsid, 'status', 'online'); break; #Found new server, don't need to keep looking for alternates } } } #Unable to find *ANY* bnls server online, guess the redirector goes down. :-( } } } echo "done."; ?> The checkserver and testserver functions are here: function checkserver($serverid, $forceupdate=false){ if(FieldVerify('id', 'servers', $serverid)){ #Server exists in database, do a query to see last check timestamp. $dtstamp = strtotime(GetInfo("servers", "id", $serverid, "dtstamp").' +1 hour'); $serverstatus = GetInfo("servers", "id", $serverid, "status"); $currentstamp = strtotime("now"); if($dtstamp > $currentstamp && !$forceupdate){ #recently cached, return data from cache $serverstatus = GetInfo("servers", "id", $serverid, "status"); if($serverstatus == 'offline'){ return false; } else { return true; } } else { #Old cache, update and return new data $ipaddress = GetInfo("servers", "id", $serverid, "serveraddress"); $serverport = GetInfo("servers", "id", $serverid, "port"); $output = @fsockopen($ipaddress, $serverport, $errno, $errstr, 2); if (!$output) { #Offline WriteInfo('servers', 'id', $serverid, 'status', 'offline'); return false; } else { #Online WriteInfo('servers', 'id', $serverid, 'status', 'online'); return true; } @fclose($output); } } else { return false; } return false; } function testServer($ipaddress, $serverport){ $output = @fsockopen($ipaddress, $serverport, $errno, $errstr, 2); if (!$output) { return false; #Offline } else { return true; #Online } @fclose($output); } The code for the The Perl script that the php script makes use of is: sed s/$1/$2/ /var/named/run-root/var/dementedminds.net > /var/named/run-root/var/dementedminds.bak rm -rf /var/named/run-root/var/dementedminds.net cp /var/named/run-root/var/dementedminds.bak /var/named/run-root/var/dementedminds.net rm -rf /var/named/run-root/var/dementedminds.bak service named reload That is inefficient as hell. Basically, the point to this is: If you go to http://bnetdocs.dementedminds.net, and click refresh a few times, you'll notice a long period of pauses before the page finishes loading. The reason for this is because of the extreme delay from the php script I coded (shown above). It shouldn't be delaying -- I had it set up so if the php script already had conducted a check for server status, to cache the results, and not do another check for a half hour. And yet, from the delay, it seems to be doing that anyway? Also, I'm not even sure if the script works as intended. I tested the php script, it works. I tested the perl script, it works like a charm if executed directly from shell (ssh). But whether both work in conjunction with each other is the real question here. If you have ideas, constructive criticism, input, etc, etc, etc, they're more than welcome. Quote Link to comment https://forums.phpfreaks.com/topic/69618-solved-phpperluse-of-php-sockets-and-using-perl-to-modify-dns-zones/ Share on other sites More sharing options...
btherl Posted September 17, 2007 Share Posted September 17, 2007 There are so many places that script could go wrong.. I recommend you print out ALL the values that might possible influence the decision on whether to use the cached value or do a fresh check. The other thing you might want to do is time some of your functions, and make sure it really is the server check and not anything else that is causing the delay (you could verify this just by commenting out the server check code, if you don't want to go to the effort of timing) A good start would be printing out $dstamp and $currentstamp right before you test them, as well as $forceupdate Quote Link to comment https://forums.phpfreaks.com/topic/69618-solved-phpperluse-of-php-sockets-and-using-perl-to-modify-dns-zones/#findComment-349831 Share on other sites More sharing options...
DonCullen Posted September 17, 2007 Author Share Posted September 17, 2007 I found the problem. It had to do with this part: $dtstamp = strtotime(GetInfo("servers", "id", $serverid, "dtstamp").' +1 hour'); $serverstatus = GetInfo("servers", "id", $serverid, "status"); $currentstamp = strtotime("now"); if($dtstamp > $currentstamp && !$forceupdate){ It wasn't converting correctly. The cache is now functioning properly, and I also optimized the code so it'd check the actual server the redirector was targeting rather than checking the redirector service itself. The page loads nicely now. I also tweaked MySQL, and also upgraded the server to PHP 5 / MySQL 5. I'm seeing a nice speed boost now. Thanks for assistance previously rendered. It is much appreciated. Quote Link to comment https://forums.phpfreaks.com/topic/69618-solved-phpperluse-of-php-sockets-and-using-perl-to-modify-dns-zones/#findComment-349973 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.