Назад | Перейти на главную страницу

балансировка нагрузки двух веб-серверов на двух разных ISP?

У меня есть два интернет-провайдера, которые предоставляют мне хостинг через apache / php / mysql. Я запускаю на них drupal. Иногда сервер mysql уходит (сбой), поэтому я надеялся найти разумный способ отработки отказа, если сервер A SQL не работает, весь трафик отправляется на сервер B.

Я знаю, что традиционно это обрабатывается в DNS, где второй альтернативный IP-адрес предоставляется, если есть проблема - или что-то подобное. Но у меня нет контроля над isp, кроме того, что я могу запускать php, perl и обычные вещи apache. Кроме того, у меня есть статические IP-адреса для каждого провайдера, и я могу создавать записи DNS (A / CNAME / TXT).

Итак, я надеялся, что у меня может быть способ создать сценарий, который проверяет, есть ли проблема с drupal, и если да, то каким-то образом изменить dns или?

Или какие-нибудь другие идеи? (кроме того, что вы тратите намного больше долларов на лучшего провайдера)

Циклический перебор DNS не решит вашу проблему - это отличный способ обеспечить балансировку нагрузки веб-серверов, но аварийное переключение происходит, когда клиент пытается подключиться к порту и не получает ответа (затем он переходит к следующей записи DNS. для хозяина). Очевидно, что если база данных MySQL выйдет из строя, это не окажет прямого влияния на веб-сервер (то есть веб-сервер будет отвечать на запросы TCP).

Хотя в принципе можно было бы получить код PHP для обнаружения сбоя базы данных и выключения веб-сервера или блокировки входящих подключений - это довольно опасный подход, даже если ваш хостинг допускает это.

Единственный практический способ, который я могу придумать для этого сценария, - это перенаправить на конкретное имя хоста в случае обнаружения сбоя, поэтому, если у вас в настоящее время оба хоста настроены как www.example.com, добавьте записи для www1 .example.com и www2.example.com, а затем добавьте автоматически добавляемый включаемый файл, чтобы сделать что-то вроде:

(on www1.example.com)
check_db();
// if check_db returns, then continue with normal processing...

function check_db() {
  if (request is for www.example.com) { // avoid loops when both sites fail
     if (last check more than 10 secs ago) {
         if (database status bad) {
            raise a database failed flag on the filesystem
            redirect to www2.example.com
            end
         }
     } else {
         if (database failed flag set) {
             redirect to www2.example.com
             end
         }
         return OK
     }
   } else { // request is for www1.example.com i.e. we are already in failover mode
     if (database failed flag set) && (last check more than 5 secs ago) {
         if (database status good) {
            remove database failed flag
            return OK
         } else { // oh no! both hosts down!
            print sorry message and exit
         }
     } else if (last check more than 5 secs ago) {
         if (database status bad) {
            raise a database failed flag on the filesystem
            print sorry message and exit
         }
     }
   }
   return OK
}

Однако вам все еще нужен способ тестирования, работает ли база данных без использования блокирующего вызова.

HTH

С.

Мне кажется, вы просите об отказе, а не о балансировке нагрузки.

Отработать отказоустойчивость крайне сложно, особенно с оборудованием, не входящим в ту же инфраструктуру. Лучшим случаем было бы получить у вашего интернет-провайдера резервный балансировщик географической нагрузки, который проверяет ваши сайты и без проблем справляется с аварийным переключением. Поскольку я предполагаю, что это выходит за рамки вашего бюджета, давайте выберем палочки и метод жевательной резинки.

Поскольку ваша проблема, по-видимому, связана с MySQL, а не с веб-сервером, давайте решим проблему вручную.

Дано:

  • Хост A: веб-сервер и база данных MySQL
  • Хост B: веб-сервер и избыточная база данных MySQL

Я бы использовал следующий метод:

  1. Храните учетные данные для подключения к базе данных где-нибудь на диске (очевидно, не в корневом веб-каталоге) и загружайте их при каждом подключении к странице. Вы можете редактировать sites / default / settings.php так:

    $ db_url = file_get_contents ('/ некоторые / частные / каталог / drupal-db.url');

  2. Напишите фоновый демон, который подключается к базе данных каждые 5 секунд (или около того) и регистрирует сбои в машиночитаемом виде на диске. После сбоя подключения через 30 секунд (или около того) затем «поменяйте местами» учетные данные, хранящиеся на диске, с учетными данными резервного сервера. Это заставит ваш веб-сервер обслуживать контент с альтернативного сервера базы данных. Если он вернется, повторите процесс в обратном порядке. Ведение журнала в этом случае необходимо для отладки и т. Д.

  3. Если вы хотите пофантазировать, вы можете попытаться записать все операции INSERT и UPDATE на диск на веб-сервере, чтобы потенциально можно было повторно синхронизировать базы данных после аварийного переключения. Если это в основном «только для чтения», то в этом нет необходимости.

Основным моментом здесь является отделение отработки отказа от работы веб-приложения. Он более модульный и упрощает внесение изменений в веб-приложение.

Наконец, убедитесь, что вы можете подключиться к базе данных резервного копирования с первичного сервера. Вы можете сделать это в командной строке и с помощью команд предоставления:

На хосте B:

mysql> GRANT ALL PRIVILEGES ON drupaldb.* TO username@'12.34.56.78' IDENTIFIED BY 'mypassword';

Если IP-адрес хоста A.

И не забывайте смывать!

mysql> FLUSH PRIVILEGES:

Затем проверьте:

bash> mysql -u username -pmypassword -h hostb drupaldb

Нет, для этого нет достойных технологий - учитывая вашу инфраструктуру.

  • DNS не будет работать, если вы не сохраните время ожидания домена DNS МАЛЕНЬКОЕ (диапазон в секундах), которое наступает. ЕСЛИ вы можете это сделать, вы можете правильно написать сценарий (сценарий на сервере 2 не может связаться с сервером 1, что изменяет записи DNS). По сути, это единственный способ сделать это.

  • В зависимости от того, как настроен ваш DNS, это будет либо там, либо - регистрация записи хоста с помощью чего-то вроде dyndns.org и замена вашей записи IN A на CNAME. DynDNS.org имеет хороший API, который вы можете вызвать через HTTP, чтобы изменить запись, и CNAME никогда не изменится. Они также держат свои домены на коротких TTL.

Это почти все варианты. Для этого есть и другие, но они требуют большого количества инфраструктуры, которой у вас нет.