short_programming_guide_for_smart_subdomains 2015/01/24 21:38 |
short_programming_guide_for_smart_subdomains 2015/01/30 00:41 current |
| | | |
| 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 === |
| 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 |
| | | |
| <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 === |
| $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 === |
| $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 === |
| { | | { |
| $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> |