This shows you the differences between the selected revision and the current version of the page.
short_programming_guide_for_smart_subdomains 2015/01/24 21:38 | short_programming_guide_for_smart_subdomains 2015/01/30 00:41 current | ||
---|---|---|---|
Line 31: | Line 31: | ||
All country names are **lower-case**. You can find a list of possible countries, including codes for Satellite Providers and Anonymous Proxies, [[http://www.maxmind.com/app/iso3166|here]]. | All country names are **lower-case**. You can find a list of possible countries, including codes for Satellite Providers and Anonymous Proxies, [[http://www.maxmind.com/app/iso3166|here]]. | ||
+ | |||
+ | **Please note**: You need to select "Share country name" in the smart subdomains form for the country information to be available to the script! | ||
=== Return serveral IPs === | === Return serveral IPs === | ||
Line 75: | Line 77: | ||
GeoScaling DNS2 can redirect based on the AS number of the network the visitor comes from. | GeoScaling DNS2 can redirect based on the AS number of the network the visitor comes from. | ||
- | If it is defined, the $as variable contains an **array** of **lower case** possible network names. The array usually contains only one element. You can make a simple redirect: | + | If it is defined, the $as variable contains the AS/ASN network id in **lower case**. You can make a simple redirect: |
<code php> | <code php> | ||
- | if( in_array("as30890", $as) ) | + | if( $as == "as6128" ) |
$output[] = array("A", "127.0.0.1"); | $output[] = array("A", "127.0.0.1"); | ||
else | else | ||
Line 87: | Line 89: | ||
<code php> | <code php> | ||
- | if( sizeof( array_intersect ( $as, array("as30890", "as24745") ) ) ) | + | if( in_array ( $as, array("as30890", "as24745", "as6128") ) ) |
$output[] = array("A", "127.0.0.1"); | $output[] = array("A", "127.0.0.1"); | ||
else | else | ||
$output[] = array("A", "127.0.0.2"); | $output[] = array("A", "127.0.0.2"); | ||
</code> | </code> | ||
+ | |||
+ | **Please note**: You need to select "Share network name / AS number" in the smart subdomains form for the network information to be available to the script! | ||
=== Redirecting on uptime information === | === Redirecting on uptime information === | ||
Line 116: | Line 120: | ||
$output[] = array("A", "96.9.130.197"); // backup mirror | $output[] = array("A", "96.9.130.197"); // backup mirror | ||
</code> | </code> | ||
+ | |||
+ | **Please note**: You need to select "Share uptime info" in the smart subdomains form for the uptime information to be available to the script! | ||
=== Redirecting based on extra information === | === Redirecting based on extra information === | ||
Line 143: | Line 149: | ||
$payload['datacenter3'] = "87"; | $payload['datacenter3'] = "87"; | ||
</code> | </code> | ||
+ | |||
+ | **Please note**: You need to select "Share extra info (like server load)" in the smart subdomains form for the extra information to be available to the script! | ||
=== Other useful variables sent to the script === | === Other useful variables sent to the script === | ||
Line 179: | Line 187: | ||
{ | { | ||
$output[] = array("A", "91.121.158.100", "400"); // return IP 91.121.158.100 with a TTL of 400 | $output[] = array("A", "91.121.158.100", "400"); // return IP 91.121.158.100 with a TTL of 400 | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | === Return the closest server to the user === | ||
+ | |||
+ | <code php> | ||
+ | $new_server['lat'] = 41.0186111; | ||
+ | $new_server['lon'] = 28.9647222; | ||
+ | $new_server['loc'] = "Istanbul TR"; | ||
+ | $new_server['ip'] = "1.2.3.4"; // IP1 | ||
+ | $servers[] = $new_server; | ||
+ | |||
+ | $new_server['lat'] = 47.6063889; | ||
+ | $new_server['lon'] = -122.3308333; | ||
+ | $new_server['loc'] = "Seattle, Wa"; | ||
+ | $new_server['ip'] = "1.2.3.5"; // IP2 | ||
+ | $servers[] = $new_server; | ||
+ | |||
+ | $new_server['lat'] = 32.7833333; | ||
+ | $new_server['lon'] = -96.8; | ||
+ | $new_server['loc'] = "Dallas, TX"; | ||
+ | $new_server['ip'] = "1.2.3.6"; // IP3 | ||
+ | $servers[] = $new_server; | ||
+ | |||
+ | $new_server['lat'] = 38.895; | ||
+ | $new_server['lon'] = -77.0366667; | ||
+ | $new_server['loc'] = "Washington D.C."; | ||
+ | $new_server['ip'] = "1.2.3.7"; // IP4 | ||
+ | $servers[] = $new_server; | ||
+ | |||
+ | $current_lat = $city_info['latitude']; | ||
+ | $current_lon = $city_info['longitude']; | ||
+ | |||
+ | $minimum_distance = PHP_INT_MAX; | ||
+ | $minimum_distance_server_id = 0; | ||
+ | |||
+ | for($i=0 ; $i<sizeof($servers); $i++) | ||
+ | { | ||
+ | $server = $servers[$i]; | ||
+ | $distance_to_user = @distance($current_lat, $current_lon, $server['lat'], $server['lon'], "k"); | ||
+ | if($distance_to_user<$minimum_distance) | ||
+ | { | ||
+ | $minimum_distance = $distance_to_user; | ||
+ | $minimum_distance_server_id = $i; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $output[] = array("A", $servers[$minimum_distance_server_id]['ip']); | ||
+ | |||
+ | /*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ | ||
+ | /*:: :*/ | ||
+ | /*:: this routine calculates the distance between two points (given the :*/ | ||
+ | /*:: latitude/longitude of those points). it is being used to calculate :*/ | ||
+ | /*:: the distance between two zip codes or postal codes using our :*/ | ||
+ | /*:: zipcodeworld(tm) and postalcodeworld(tm) products. :*/ | ||
+ | /*:: :*/ | ||
+ | /*:: definitions: :*/ | ||
+ | /*:: south latitudes are negative, east longitudes are positive :*/ | ||
+ | /*:: :*/ | ||
+ | /*:: passed to function: :*/ | ||
+ | /*:: lat1, lon1 = latitude and longitude of point 1 (in decimal degrees) :*/ | ||
+ | /*:: lat2, lon2 = latitude and longitude of point 2 (in decimal degrees) :*/ | ||
+ | /*:: unit = the unit you desire for results :*/ | ||
+ | /*:: where: 'm' is statute miles :*/ | ||
+ | /*:: 'k' is kilometers (default) :*/ | ||
+ | /*:: 'n' is nautical miles :*/ | ||
+ | /*:: united states zip code/ canadian postal code databases with latitude & :*/ | ||
+ | /*:: longitude are available at http://www.zipcodeworld.com :*/ | ||
+ | /*:: :*/ | ||
+ | /*:: For enquiries, please contact sales@zipcodeworld.com :*/ | ||
+ | /*:: :*/ | ||
+ | /*:: official web site: http://www.zipcodeworld.com :*/ | ||
+ | /*:: :*/ | ||
+ | /*:: hexa software development center © all rights reserved 2004 :*/ | ||
+ | /*:: :*/ | ||
+ | /*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ | ||
+ | |||
+ | //echo distance(32.9697, -96.80322, 29.46786, -98.53506, "m") . " miles<br>"; | ||
+ | //echo distance(32.9697, -96.80322, 29.46786, -98.53506, "k") . " kilometers<br>"; | ||
+ | //echo distance(32.9697, -96.80322, 29.46786, -98.53506, "n") . " nautical miles<br>"; | ||
+ | |||
+ | |||
+ | function distance($lat1, $lon1, $lat2, $lon2, $unit) | ||
+ | { | ||
+ | |||
+ | $theta = $lon1 - $lon2; | ||
+ | $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); | ||
+ | $dist = acos($dist); | ||
+ | $dist = rad2deg($dist); | ||
+ | $miles = $dist * 60 * 1.1515; | ||
+ | $unit = strtoupper($unit); | ||
+ | |||
+ | if ($unit == "K") { | ||
+ | return ($miles * 1.609344); | ||
+ | } else if ($unit == "N") { | ||
+ | return ($miles * 0.8684); | ||
+ | } else { | ||
+ | return $miles; | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | === Output debug information in TXT records === | ||
+ | |||
+ | This simple script generates TXT records with the information GeoScaling sends to your script: | ||
+ | |||
+ | <code php> | ||
+ | $output[] = array("TXT", "City Info: ".var_export($city_info, true)); | ||
+ | $output[] = array("TXT", "Network info: ".var_export($as, true)); | ||
+ | $output[] = array("TXT", "Country: ".$country); | ||
+ | $output[] = array("TXT", "Subdomain: ".$subdomain); | ||
+ | $output[] = array("TXT", "Remote IP: ".$remote_ip);</code> | ||
+ | |||
+ | Now, if you make a DNS request for the TXT records of your subdomain: | ||
+ | |||
+ | <code> | ||
+ | dig -t TXT geo.nyuu.org @ns1.geoscaling.com | ||
+ | </code> | ||
+ | |||
+ | you will get something like this: | ||
+ | |||
+ | <code> | ||
+ | ... | ||
+ | ;; ANSWER SECTION: | ||
+ | geo.nyuu.org. 300 IN TXT "Remote IP: 67.82.29.100" | ||
+ | geo.nyuu.org. 300 IN TXT "Network info: 'as6128'" | ||
+ | geo.nyuu.org. 300 IN TXT "City Info: array ( 'city' => 'newark', 'country' => 'us', 'region' => 'nj', 'latitude' => 40.734, 'longitude' => -74.1868, )" | ||
+ | geo.nyuu.org. 300 IN TXT "Country: us" | ||
+ | geo.nyuu.org. 300 IN TXT "Subdomain: geo.nyuu.org" | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | User contribution that combines, Closest, plus uptime / take server offline, plus send extra info to take server offline during a deployment | ||
+ | See send extra_info wiki part, to see the php code that sends the associated extra_info via a URL | ||
+ | <code php> | ||
+ | /* | ||
+ | GeoScaling "smart subdomain script" | ||
+ | PURPOSE: | ||
+ | 1/ associate url/IP with the physically closest server, monitoring with www.monitis.com reveals minimum of 2x improvement in latency if we do this | ||
+ | 2/ take a server out of the list of possible servers if GeoScaling monitoring shows it as down | ||
+ | 3/ take a sever out of the list (immediate effect) if we are about to deploy an upgrade of the app software by sending "extra_info" | ||
+ | |||
+ | Contributed BY: keitht@sasimedia.net | ||
+ | AVAILABLE INFRASTRUCTURE CONSULTING ON | ||
+ | 1/ automated build and deploy the N servers in the cloud | ||
+ | 2/ Unix or Windows cloud server setup (linode / Rackspace / other) | ||
+ | 3/ Techniques for achieving fastest initial page load | ||
+ | 4/ No SQL keystore for database replication across cloud servers (Hazelcast + Voldemort + Oracle BDB) | ||
+ | 5/ HA / 100 % uptime | ||
+ | 6/ Smart browser clients (Flex / GWT), with service calls automatically tied to the fastest responding server (not necessarily the closest) | ||
+ | */ | ||
+ | |||
+ | $info = unserialize($extra_info); | ||
+ | |||
+ | if($uptime['Linode-s1.info']==1 && strcmp($info['linode-s1-offline'],'true') != 0){ | ||
+ | $new_server['lat'] = 37.4919627; | ||
+ | $new_server['lon'] = -121.93811; | ||
+ | $new_server['loc'] = "Fremont, California"; | ||
+ | $new_server['ip'] = "1.1.1.1"; //linode-s1 CA | ||
+ | $servers[] = $new_server; | ||
+ | } | ||
+ | |||
+ | if($uptime['rackspace-s1.info']==1 && strcmp($info['rackspace-s1-offline'],'true') != 0){ | ||
+ | $new_server['lat'] = 32.7833333; | ||
+ | $new_server['lon'] = -96.8; | ||
+ | $new_server['loc'] = "Dallas, TX"; | ||
+ | $new_server['ip'] = "1.1.1.1"; //rackspace-s1 DALLAS | ||
+ | $servers[] = $new_server; | ||
+ | } | ||
+ | |||
+ | if($uptime['rackspace-s1.info']==1 && strcmp($info['rackspace-s2-offline'],'true') != 0){ | ||
+ | $new_server['lat'] = 41.85; | ||
+ | $new_server['lon'] = -87.65; | ||
+ | $new_server['loc'] = "Chicago, IL"; | ||
+ | $new_server['ip'] = "1.1.1.1"; // rackspace-s2 CHICAGO | ||
+ | $servers[] = $new_server; | ||
+ | } | ||
+ | |||
+ | if($uptime['Linode-s2.info']==1 && strcmp($info['linode-s2-offline'],'true') != 0){ | ||
+ | $new_server['lat'] = 33.73; | ||
+ | $new_server['lon'] = -84.38; | ||
+ | $new_server['loc'] = "Atlanta, GA."; | ||
+ | $new_server['ip'] = "11.1.1.1"; // linode-s2 ATLANTA | ||
+ | $servers[] = $new_server; | ||
+ | } | ||
+ | |||
+ | $current_lat = $city_info['latitude']; | ||
+ | $current_lon = $city_info['longitude']; | ||
+ | |||
+ | $minimum_distance = PHP_INT_MAX; | ||
+ | $minimum_distance_server_id = 0; | ||
+ | |||
+ | for($i=0 ; $i<sizeof($servers); $i++) | ||
+ | { | ||
+ | $server = $servers[$i]; | ||
+ | $distance_to_user = @distance($current_lat, $current_lon, $server['lat'], $server['lon'], "k"); | ||
+ | if($distance_to_user<$minimum_distance) | ||
+ | { | ||
+ | $minimum_distance = $distance_to_user; | ||
+ | $minimum_distance_server_id = $i; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $output[] = array("A", $servers[$minimum_distance_server_id]['ip']); | ||
+ | |||
+ | /*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ | ||
+ | /*:: :*/ | ||
+ | /*:: this routine calculates the distance between two points (given the :*/ | ||
+ | /*:: latitude/longitude of those points). it is being used to calculate :*/ | ||
+ | /*:: the distance between two zip codes or postal codes using our :*/ | ||
+ | /*:: zipcodeworld(tm) and postalcodeworld(tm) products. :*/ | ||
+ | /*:: :*/ | ||
+ | /*:: definitions: :*/ | ||
+ | /*:: south latitudes are negative, east longitudes are positive :*/ | ||
+ | /*:: :*/ | ||
+ | /*:: passed to function: :*/ | ||
+ | /*:: lat1, lon1 = latitude and longitude of point 1 (in decimal degrees) :*/ | ||
+ | /*:: lat2, lon2 = latitude and longitude of point 2 (in decimal degrees) :*/ | ||
+ | /*:: unit = the unit you desire for results :*/ | ||
+ | /*:: where: 'm' is statute miles :*/ | ||
+ | /*:: 'k' is kilometers (default) :*/ | ||
+ | /*:: 'n' is nautical miles :*/ | ||
+ | /*:: united states zip code/ canadian postal code databases with latitude & :*/ | ||
+ | /*:: longitude are available at http://www.zipcodeworld.com :*/ | ||
+ | /*:: :*/ | ||
+ | /*:: For enquiries, please contact sales@zipcodeworld.com :*/ | ||
+ | /*:: :*/ | ||
+ | /*:: official web site: http://www.zipcodeworld.com :*/ | ||
+ | /*:: :*/ | ||
+ | /*:: hexa software development center © all rights reserved 2004 :*/ | ||
+ | /*:: :*/ | ||
+ | /*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ | ||
+ | |||
+ | //echo distance(32.9697, -96.80322, 29.46786, -98.53506, "m") . " miles<br>"; | ||
+ | //echo distance(32.9697, -96.80322, 29.46786, -98.53506, "k") . " kilometers<br>"; | ||
+ | //echo distance(32.9697, -96.80322, 29.46786, -98.53506, "n") . " nautical miles<br>"; | ||
+ | |||
+ | |||
+ | function distance($lat1, $lon1, $lat2, $lon2, $unit) | ||
+ | { | ||
+ | |||
+ | $theta = $lon1 - $lon2; | ||
+ | $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); | ||
+ | $dist = acos($dist); | ||
+ | $dist = rad2deg($dist); | ||
+ | $miles = $dist * 60 * 1.1515; | ||
+ | $unit = strtoupper($unit); | ||
+ | |||
+ | if ($unit == "K") { | ||
+ | return ($miles * 1.609344); | ||
+ | } else if ($unit == "N") { | ||
+ | return ($miles * 0.8684); | ||
+ | } else { | ||
+ | return $miles; | ||
+ | } | ||
} | } | ||
</code> | </code> |