Jump to content

[SOLVED] PHP/Perl/Use of PHP sockets, and using Perl to modify DNS zones...


DonCullen

Recommended Posts

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.