Amazon Route 53 and site uptime

Amazon
Over the past 3 weeks, I have had to experience interruptions in the work of my hosting several times, since I am conducting a project with high traffic, even a short-term downtime affects the number of calls from the site.
Moreover, everything could have been much better if, instead of the standard page “Server not found”, hang up a screensaver in the style of the site with the text “The site is temporarily unavailable, call or leave a request.”
It was decided to use Amazon's DNS service to quickly change the A record.



Description of Amazon Route 53

This is a reliable DNS service, with a fairly convenient API for editing, adding and deleting records.
The cost of the service is $ 1 per month + $ 0.50 for the first million requests and $ 0.25 for each subsequent million requests.
A serious inconvenience in some cases is the payment method - you can pay for the service only with a plastic card, but there is a way out, for example, you can use the Visa virtual card from qiwi .
After registration and payment for the service, we get a pair of ID and key, which are subsequently used for authorization in the API.

Cooking domain

It’s not very convenient to use the API to connect the domain and configure all the necessary entries.
I suggest using the Interstate53 service .
The service is an interface for managing an account on Route 53 and provides a full range of its functions.
Interstate53
We fill in all the records as before - A-records go to the IP address of the main hosting.

Choose a hosting

In my case, the backup server should be as cheap as possible and have the following set of functions:
  • PHP - for working with Route 53 API
  • cron - to periodically check the main hosting for availability
  • static HTML - to display a splash screen

The choice fell on Gino , this is the only hosting that I found where you can refuse to support databases without abandoning PHP. The price came out 75 rubles a month.
The main hosting is clodo , although it does not matter.

Configure basic hosting

We are interested in the performance of the site in any conditions, which means that if the database freezes or apache you must also change the A-record. For testing, we’ll create a small PHP script accessible by the server’s IP address.
  1.  
  2. $link = mysql_connect('localhost', 'root', 'password') or die('0');
  3. $result = mysql_query('SELECT VERSION();');
  4. if(!$result)
  5.         die('0');
  6. mysql_close($link);
  7. echo 'OK!';
  8.  

In case of problems with the database, the script will return 0, if the server does not work or apache freezes, the script will not give anything, if successful, the message “OK!” Will be transmitted.
This completes the setup of the primary server.

Configure duplicate hosting

To work with the Route 53 API, I used the ready-made PHP class Route53 .
  1.  
  2. define('MASTER_HOST', 'xxx.xxx.xxx.xxx');//IP адрес основного сервера
  3. define('SLAVE_HOST', 'xxx.xxx.xxx.xxx');//IP адрес дополнительного сервера
  4. define('ACCESS_KEY', 'my_key');//Ключ для доступа к API
  5. define('SECRET_KEY', 'my_pass');//Пароль для доступа к API
  6. define('ZONE_ID', '/hostedzone/my_zone_id');//ID зоны (можно увидеть после добавлени домена в interstate53.com)
  7.  
  8. include 'r53.php';
  9. $route = new Route53(ACCESS_KEY, SECRET_KEY);
  10. $ns = $route->listResourceRecordSets(ZONE_ID);//Сразу получаем значения ns записей для домена
  11.  
  12. function test(){
  13.         try{
  14.                 $answer = file_get_contents('http://'.MASTER_HOST.'/');
  15.                 if($answer == 'OK!')//Проверяем ответ от основного сервера
  16.                         return true;
  17.                 else
  18.                         return false;
  19.         }catch (Exception $e){
  20.                 return false;
  21.         }
  22. }
  23.  
  24. function update($arr){
  25.         GLOBAL $route;
  26.         if(count($arr) > 0)
  27.         {
  28.                 $route->changeResourceRecordSets(ZONE_ID, $arr);//Обновление ns-записей
  29.         }
  30. }
  31.  
  32. function changeIP($name, $ttl, $from_ip, $to_ip){//Функция генерирует массив в котором одна запись удаляет старую, а вторая добавляет новую
  33.         return Array(
  34.                 "
  35.                
  36.                         DELETE
  37.                        
  38.                                 $name
  39.                                 A
  40.                                 $ttl
  41.                                
  42.                                        
  43.                                                 $from_ip
  44.                                        
  45.                                
  46.                        
  47.                
  48.                 ",
  49.                 "
  50.                
  51.                         CREATE
  52.                        
  53.                                 $name
  54.                                 A
  55.                                 $ttl
  56.                                
  57.                                        
  58.                                                 $to_ip
  59.                                        
  60.                                
  61.                        
  62.                
  63.                 "
  64.         );
  65. }
  66.  
  67. $changes = Array();
  68.  
  69. if(!test()){
  70.         if(!test()){// делаем проверку 2 раза для надёжности
  71.                 foreach($ns['ResourceRecordSets'] as $record){
  72.                         if($record['Type'] == 'A' && $record['ResourceRecords']['0'] == MASTER_HOST){
  73.                                 $changes = array_merge($changes, changeIP($record['Name'], $record['TTL'], MASTER_HOST, SLAVE_HOST));
  74.                         }
  75.                 }
  76.                 update($changes);
  77.                 exit(0);
  78.         }
  79. }
  80.  
  81. foreach($ns['ResourceRecordSets'] as $record){
  82.         if($record['Type'] == 'A' && $record['ResourceRecords']['0'] == SLAVE_HOST){
  83.                 $changes = array_merge($changes, changeIP($record['Name'], $record['TTL'], SLAVE_HOST, MASTER_HOST));
  84.         }
  85. }
  86. update($changes);
  87. exit(0);
  88.  


I summarize the code a little in order: we check the server for the answer “OK!” 2 times for reliability, if the answer is incorrect, we change the records, if the answer is correct, we return the records to the place.

It remains to configure cron

In Gino, this is done quite simply, we throw the resulting script into the folder of the test domain mydomain.jino.ru, click "New Task" in the "Scheduled Tasks", then fill in the fields:
Task: curl -s mydomain.jino.ru/route53/core .php > / dev / null
Comment:
Minutes, Hours, Days, Months, Days of the week: *
Our script will be executed every minute. This means that the maximum downtime of the site will be 2 minutes 29 seconds in the worst scenario and 30 seconds (depending on the TTL A record) at best.

Total

Ideally, of course, you should keep a copy of the site on additional hosting - a splash screen with contacts and the inscription "the server is not working" can scare some people away. But this method also has a right to exist.

Also popular now: