📜 ⬆️ ⬇️

Amazon Route 53 and the smooth running of the site

Amazon
Over the past 3 weeks, I have had several times to encounter interruptions in my hosting, since I am running a project with a lot of traffic, even a short-term idle time affects the number of calls from the site.
At the same time, everything could be much better, if instead of the standard “Server not found” page, hang up a splash screen in the style of the site with the text “The site is temporarily unavailable, call or request.”
It was decided to use the DNS service from Amazon to quickly change the A-record.



Amazon Route 53 Description

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 next million requests.
A serious inconvenience in some cases is the payment method - you can pay for the service only by a plastic card, but there is a way out, for example, you can use the virtual Visa card from qiwi .
After registering and paying for the service, we get a pair of IDs and a key, which are subsequently used for authorization in the API.
')
We are preparing a domain

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

Choosing a hosting

In my case, the backup server should be as cheap as possible and have the following set of functions:

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

We configure the main hosting

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

In case of problems with the database, the script will issue 0, if the server is not working or apache freezes, the script will not issue anything, if successful, the “OK!” Message will be transmitted.
This completes the configuration of the main server.

Configuring backup hosting

To work with the Route 53 API, I used the ready-made PHP class Route53 .
  1. define ( 'MASTER_HOST' , 'xxx.xxx.xxx.xxx' ) ; // IP address of the main server
  2. define ( 'SLAVE_HOST' , 'xxx.xxx.xxx.xxx' ) ; // IP address of the secondary server
  3. define ( 'ACCESS_KEY' , 'my_key' ) ; // API Access Key
  4. define ( 'SECRET_KEY' , 'my_pass' ) ; // Password for access to API
  5. define ( 'ZONE_ID' , '/ hostedzone / my_zone_id' ) ; // ID of the zone (can be seen after adding the domain to interstate53.com)
  6. include 'r53.php' ;
  7. $ route = new Route53 ( ACCESS_KEY , SECRET_KEY ) ;
  8. $ ns = $ route -> listResourceRecordSets ( ZONE_ID ) ; // Immediately get the values ​​of ns records for the domain
  9. function test ( ) {
  10. try {
  11. $ answer = file_get_contents ( 'http: //' . MASTER_HOST . '/' ) ;
  12. if ( $ answer == 'OK!' ) // Check the response from the main server
  13. return true ;
  14. else
  15. return false ;
  16. } catch ( Exception $ e ) {
  17. return false ;
  18. }
  19. }
  20. function update ( $ arr ) {
  21. GLOBAL $ route ;
  22. if ( count ( $ arr ) > 0 )
  23. {
  24. $ route -> changeResourceRecordSets ( ZONE_ID , $ arr ) ; // Update ns records
  25. }
  26. }
  27. function changeIP ( $ name , $ ttl , $ from_ip , $ to_ip ) { // The function generates an array in which one record deletes the old one, and the second adds a new one
  28. return array (
  29. "
  30. <Change>
  31. <Action> DELETE </ Action>
  32. <ResourceRecordSet>
  33. <Name> $ name </ name>
  34. <Type> A </ Type>
  35. <TTL> $ ttl </ TTL>
  36. <ResourceRecords>
  37. <ResourceRecord>
  38. <Value> $ from_ip </ Value>
  39. </ ResourceRecord>
  40. </ ResourceRecords>
  41. </ ResourceRecordSet>
  42. </ Change>
  43. " ,
  44. "
  45. <Change>
  46. <Action> CREATE </ Action>
  47. <ResourceRecordSet>
  48. <Name> $ name </ name>
  49. <Type> A </ Type>
  50. <TTL> $ ttl </ TTL>
  51. <ResourceRecords>
  52. <ResourceRecord>
  53. <Value> $ to_ip </ Value>
  54. </ ResourceRecord>
  55. </ ResourceRecords>
  56. </ ResourceRecordSet>
  57. </ Change>
  58. "
  59. ) ;
  60. }
  61. $ changes = Array ( ) ;
  62. if ( ! test ( ) ) {
  63. if ( ! test ( ) ) { // do a test 2 times for reliability
  64. foreach ( $ ns [ 'ResourceRecordSets' ] as $ record ) {
  65. if ( $ record [ 'Type' ] == 'A' && $ record [ 'ResourceRecords' ] [ '0' ] == MASTER_HOST ) {
  66. $ changes = array_merge ( $ changes , changeIP ( $ record [ 'Name' ] , $ record [ 'TTL' ] , MASTER_HOST , SLAVE_HOST ) ) ;
  67. }
  68. }
  69. update ( $ changes ) ;
  70. exit ( 0 ) ;
  71. }
  72. }
  73. foreach ( $ ns [ 'ResourceRecordSets' ] as $ record ) {
  74. if ( $ record [ 'Type' ] == 'A' && $ record [ 'ResourceRecords' ] [ '0' ] == SLAVE_HOST ) {
  75. $ changes = array_merge ( $ changes , changeIP ( $ record [ 'Name' ] , $ record [ 'TTL' ] , SLAVE_HOST , MASTER_HOST ) ) ;
  76. }
  77. }
  78. update ( $ changes ) ;
  79. exit ( 0 ) ;


I briefly summarize the code in order: we check the server for the answer “OK!” 2 times for reliability, if the answer is not correct, change the records, if the answer is correct, 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 mydomain.jino.ru test domain folder, in the “Scheduled Tasks” click “New Task”, 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 site downtime will be 2 minutes 29 seconds in the worst scenario and 30 seconds (depending on the TTL of the A record) at the best.

Total

Ideally, of course, you should keep a copy of the site on additional hosting - a screensaver with contacts and the words “server does not work” may scare away some people. But this method also has the right to exist.

Source: https://habr.com/ru/post/122238/


All Articles