load balancing dois servidores web em dois isp's diferentes?

2

Eu tenho dois provedores que me fornecem hospedagem via apache / php / mysql. Eu estou correndo drupal neles. Ocasionalmente, o servidor mysql irá embora (crash), então eu estava esperando encontrar uma maneira razoável de ter um failover, se o servidor A SQL está inoperante, todo o tráfego é enviado para o servidor B.

Eu sei que tradicionalmente isso é tratado no DNS, onde um segundo ip alternativo é dado se houver um problema - ou similar. Mas eu não tenho controle sobre o isp, além de poder rodar o php, o perl e as coisas usuais do apache. Além disso, tenho IP estático em cada isp e posso criar entradas de DNS (A / CNAME / TXT).

Então, eu estava esperando que houvesse uma maneira de eu ter um script que verifique se o drupal tem um problema e, em caso afirmativo, de alguma forma altere dns ou?

Ou alguma outra ideia? (além de gastar muito mais em um isp melhor)

    
por Scott Szretter 20.04.2010 / 13:14

3 respostas

2

O Round Robin DNS não resolverá seu problema - é uma ótima maneira de fornecer balanceamento de carga de servidores Web - mas o failover ocorre quando o cliente tenta se conectar a uma porta e não recebe resposta (em seguida, tenta testar o próxima entrada DNS para o host). Obviamente, se o banco de dados MySQL falhar, isso não terá impacto direto no servidor da Web (ou seja, o servidor responderá às solicitações TCP).

Embora seja possível, em princípio, obter o código PHP para detectar uma falha no banco de dados e desligar o servidor web ou bloquear conexões de entrada - essa é uma abordagem perigosa - mesmo que sua hospedagem permita que isso aconteça.

A única maneira prática que posso pensar para lidar com esse cenário é redirecionar para um nome de host específico no caso de uma detecção de falha, por isso, se você tiver os dois hosts configurados como www.example.com, adicione registros para www1.example.com e www2.example.com e adicione um arquivo de inclusão com prefixo automático para fazer algo como:

(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
}

No entanto, você ainda precisa testar se o banco de dados está funcionando sem usar uma chamada de bloqueio.

HTH

C.

    
por 20.04.2010 / 13:57
1

Você está solicitando failover, não balanceamento de carga, methinks.

O failover é extremamente difícil de fazer bem, especialmente com equipamentos que não estão dentro da mesma infraestrutura. O melhor caso seria obter um balanceador de carga geográfica redundante no seu provedor de serviços de Internet que testa seus sites e lida com o failover de maneira perfeita. Uma vez que o meu palpite é que está fora do seu orçamento, vamos para o método de varas e chiclete.

Como o seu problema aparentemente é o MySQL, não o servidor web, então vamos resolver o problema em questão.

Dado:

  • Host A: Servidor Web e banco de dados MySQL
  • Host B: servidor da Web e banco de dados MySQL redundante

O método que eu usaria seria:

  1. Armazene suas credenciais de conexão de banco de dados no disco em algum lugar (obviamente, não dentro da raiz da web) e carregue-as em cada conexão de página. Você pode editar sites / default / settings.php da seguinte forma:

    $ db_url = file_get_contents ('/ algumas / private / dir / drupal-db.url');

  2. Grave um daemon de plano de fundo que se conecte ao banco de dados a cada 5 segundos (ou mais) e registre falhas em um disco legível por máquina. Depois que a conexão falhar após 30 segundos (ou mais), "troque" as credenciais armazenadas no disco com as do servidor de backup. Isso fará com que seu servidor da Web exiba conteúdo do servidor de banco de dados alternativo. Se voltar, inverta o processo. O registro é essencial neste caso para depuração, etc.

  3. Se quiser ficar chique, você pode tentar registrar todos os INSERT e UPDATE em disco no servidor web, para que você possa re-sincronizar os bancos de dados após um failover. Se for principalmente "somente leitura", isso pode não ser necessário.

O principal ponto aqui é dissociar o failover da operação do aplicativo da web. É mais modular e simplifica as alterações no aplicativo da Web.

Por fim, verifique se você pode se conectar ao seu banco de dados de backup a partir do servidor principal. Você pode fazer isso na linha de comando e usar comandos grant:

No host B:

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

Onde o IP é do Host A.

E não se esqueça de dar descarga!

mysql> FLUSH PRIVILEGES:

Então teste:

bash> mysql -u username -pmypassword -h hostb drupaldb
    
por 20.04.2010 / 15:58
0

De jeito nenhum, não há tecnologia decente para isso - dada sua infra-estrutura.

  • O DNS não funcionará, a menos que você mantenha o tempo limite do domínio DNS pequeno (intervalo de segundos), o que é pouco esperado. Se você puder fazer isso, você pode fazer o script corretamente (o script no servidor 2 não pode acessar o servidor 1, alterando assim as entradas de DNS). Essa é a única maneira de fazer isso.

  • Dependendo de como sua configuração de DNS é, isso estaria lá, OR - registrando uma entrada de host usando algo como dyndns.org e substituindo sua entrada IN A por um CNAME. DynDNS.org tem uma boa API que você poderia chamar via HTTP para alterar a entrada, e o CNAME nunca mudaria. Eles também mantêm seus domínios em TTLs curtos.

Isso é praticamente tudo. Existem outros para isso, mas eles exigem muita infraestrutura que você não possui.

    
por 20.04.2010 / 13:24