Como implementar Failover e Load Balance no DataSnap 2010

Categories:DelphiTags: , ,

Uma pergunta frequente dos desenvolvedores durante as minhas viagens pela America Latina está relacionado ao desenvolvimento multicamada com DataSnap, após explicar toda a tecnologia sempre vem a pergunta “Como implementar Failover e Load Balance neste tipo de aplicação, o que é mais do que natural.

Quando pensamos em servidores de aplicação como parte do nosso desenvolvimento multicamada temos como um dos objetivos centralizar processamento, investimento em hardware, atualizações, etc. Quando pensamos em centralizar precisamos pensar também em redundância, ou seja, se um servidor falhar outro deve assumir, também pensamos em dividir a carga de processamento, ou seja, de acordo com o volume de processamento de cada servidor no

momento redirecionamos a carga para que estiver menos sobrecarregado, chamamos isso de load balance.

Implementar essas duas características até então não era algo muito simples e exigia muito código, agora com o DataSnap 2010 a história é bem diferente.

DataSnap 2010 traz um recurso chamado HTTP Tunneling que lhe permite o controle do direcionamento da informação que está sendo enviada/recebida entre cliente e servidor. Como o próprio nome diz HTTP Tunneling, você terá que utilizar HTTP como Transporter na sua aplicação cliente para usufruir destas vantagens, o que não é um problema. Caso você queira utilizar TCP/IP na aplicação cliente, não será possível utilizar este recurso de forma simples, então recomendo utilizar HTTP.

Implementar Load Balance e Failover quer dizer criar um middleware entre a aplicação cliente e servidora, este middleware será responsável por decidir o que fazer com a informação recebida, para onde enviar, quando enviar, como enviar, etc.

Traduzindo isso para o mundo DataSnap, teremos uma aplicação cliente conectando a um servidor que neste caso chamaremos de Failover e o servidor DataSnap, o servidor de Failover será o nosso Firewall, neste post vou simular a queda de um servidor DataSnap e automaticamente a conexão será direcionada para outro servidor DataSnap.

Não é necessário fazer grandes mudanças na sua aplicação para suportar HTTP Tunneling, basicamente é ter a aplicação cliente conectando ao servidor de Failover através de HTTP, do servidor de Failover para o servidor DataSnap você poderá usar TCP/IP ou HTTP.

O servidor Failover terá apenas 2 componentes, o DSHTTPService que representa o seu Failover Server e estará conectado ao DSHTTPServiceAuthenticationManager, apenas para questões de segurança, pois quero que somente pessoas autorizadas conectem a este servidor.

Para habilitar o recurso de HTTP Tunneling você terá que implementar os eventos referente ao HTTP Service Tunnel Service, que são:

  • DSHTTPService1.HttpServer.TunnelService.OnErrorOpenSession
  • DSHTTPService1.HttpServer.TunnelService.OnErrorWriteSession
  • DSHTTPService1.HttpServer.TunnelService.OnErrorReadSession
  • DSHTTPService1.HttpServer.TunnelService.OnOpenSession
  • DSHTTPService1.HttpServer.TunnelService.OnWriteSession
  • DSHTTPService1.HttpServer.TunnelService.OnReadSession
  • DSHTTPService1.HttpServer.TunnelService.OnCloseSession

Cada um destes eventos será executado na sua ordem natural ou quando algum erro ocorrer, os nomes de cada evento são obvios, a aplicação exemplo implementa todos estes eventos, com o objetivo de mostrar no log as informações enviadas e recebidas durante a utilização da mesma.

No caso de uma solução de Failover todos os eventos devem ser implementados, os eventos OnErrorXXX entrarão em ação quando um erro ocorrer e necessitam do conteúdo que está sendo transferido para saber o que fazer, assim sendo eles dependem dos outros eventos. Neste posto vou focar no evento OnErrorOpenSession o qual irá efetuar o redirecionamento em caso de error na abertura de sessão.

Abaixo a implementação do método chamado Redirect que esta associado ao evento OnErrorOpenSession, repare que os dados da Sessão e conteúdo são parâmetros neste método, ou seja, tudo o que precisamos para poder redirecionar a informação.

Como controle estamos utilizando o Session.UserFlag, para permitir apenas um redirecionamento e caso o Sender seja uma Exception vamos armazenar a mensagem de error. A seguir criamos um DBXProperties que contém as informações do novo servidor que deverá ser redirecionado, neste exemplo utilizei o mesmo HostName, mas a porta será a 213, ou seja, tenho outro servidor DataSnap.

A partir dai basta reabrir a sessão com as novas propriedades que a mesma será redirecionada para o novo servidor.

Você pode estar achando fácil demais, na verdade é muito fácil.

procedure TForm6.Redirect(Sender: TObject; Session: TDSTunnelSession; Content: TBytes; var Count: Integer);
var
  DBXProperties: TDBXDatasnapProperties;
  Msg: String;
begin
  if Sender is Exception then
    Msg := Exception(Sender).Message;
  Log('>>' + Msg);

  if Session.UserFlag = 1 then
    Raise Exception.Create('Backup session cannot be redirected once more.' + Msg);

  DBXProperties := TDBXDatasnapProperties.Create(nil);
  DBXProperties.Values[TDBXPropertyNames.DriverName] := 'Datasnap';
  DBXProperties.Values[TDBXPropertyNames.HostName]  := 'localhost';
  DBXProperties.Values[TDBXPropertyNames.Port]      := '213';

  try
    try
      Session.Reopen(DBXProperties);
      Session.UserFlag := 1;

      Msg := 'Flow commuted to alternate resource.';
      Log('>>' + Msg);
    except
      Raise Exception.Create(Msg + '. Commuting to alternate resource failed.');
    end;
  finally
    DBXProperties.free;
  end;

end;

Claro que você está curioso pra saber como funciona a execução, o que você precisa é um servidor DataSnap, servidor Failover e a aplicação cliente, neste caso utilize o próprio Data Explorer do Delphi será utilizando como aplicação cliente. A seguir os passos para executar este exemplo:

  1. Execute o servidor Failover, o exemplo utiliza HTTP e porta 8080
  2. Execute 2 instâncias do servidor DataSnap, uma na porta 211 e outra na porta 213, o servidor na porta 213 será o servidor de backup em caso de falho do servidor que está na porta 211
  3. Crie um DataSnap alias no Data Explorer, lembre-se de utilizar o protocolo HTTP e porta 8080
  4. Execute o método EchoString que aparece na lista de Procedures, passe o valor Delphi 2010 como parâmetro e execute, veja que o retorno será Delphi 2010 (Server 211)
  5. Feche a aplicação DataSnap server, porta 211
  6. Repita o passo número 4 e veja que o retorno será Delphi 2010 (Server 213)
  7. Veja o log no servidor Failover, você verá uma exception e o redirecionamento ocorrendo

Para facilitar o entendimento preparei um vídeo apresentando como executar este exemplo.

Você pode efetuar o download do código fonte aqui

Para outros posts relacionados ao DataSnap, clique aqui

Posts relacionados

26 Responses to Como implementar Failover e Load Balance no DataSnap 2010

  1. Tweets that mention Como implementar Failover e Load Balance no DataSnap 2010 | Delphi 2010 | Andreano Lanusse Blog -- Topsy.com says:

    [...] This post was mentioned on Twitter by Andreano Lanusse, Ramos da Informática. Ramos da Informática said: RT @andreanolanusse: Blog post: Como implementar Failover e Load Balance no DataSnap 2010 http://bit.ly/7tpt2m #Delphi #DataSnap [...]

  2. Rafael says:

    Andreano, muito bom o post, parabéns. Só uma observação, o código fonte que você indicou não tem a fonte do Failover. No 27391 não encontrei.

  3. Andreano Lanusse says:

    Oi Rafael, baixa de novo o arquivo, acabei de atualizar. Sorry e feliz ano novo!!!

  4. Rafael says:

    Sem problemas, obrigado Andreano, Feliz Ano Novo e Sucesso no próximo ano !!!

  5. Elton says:

    Muito legal este artigo. Parabéns Adriano.

    Tenho apenas uma dúvida:
    E se ao invés de um dos servidores de aplicação, a máquina onde estiver o Failover “cair”, o que acontece? Será que não volta tudo ao problema original? Isto quer dizer, de nada teria adiantado investir neste conceito, pois a aplicação deixaria de funcionar, mesmo estando os dois servidores de aplicação operacionais… Esta situação pode ocorrer?

  6. Andreano Lanusse says:

    Oi Eilton,

    É uma boa pergunta, qualquer solução de redundância você terá esse risco, neste caso eu deveria ter uma redundância para o servidor de failover, lembro que aqui estou criando uma redundância para os servidores datasnap.

    Como o servidor de failover conecta através de HTTP, você pode aqui ter várias formas de implementar redundância, umas delas através de roteamento direto em caso de queda do servidor Failover.

    No final é melhor ter a redundância nos servidores DataSnap e garantir uma boa infraestrutura para suportar o servidor de failover.

  7. Christiano Coutinho says:

    Andreano, parei no tempo no Delphi (2007), mas pelo que me lembro do DataSnap, o balanceamento de carga era meio tosco: era implementado através de um sorteio em uma lista de app. servers. Para fazer um balanceamento de cargas mais eficiente, eu tinha que criar um serviço para monitorar os app. servers , conseguindo assim priorizar a carga dos servers mais ociosos, ao invés de um simples sorteio. Isso mudou na nova versão ou continua do mesmo jeito?

  8. Andreano Lanusse says:

    Christiano, no caso de balanceamento de carga você poderá reutilizar essa solução que você criou com o novo DataSnap, pois o redirecionamento é feito de forma muito simples, o que antes era meio complicado.

  9. Balanceamento de Carga e Tolerância a Falha no Delphi 2010 says:

    [...] ler o artigo na integra acesse o blog do Andreano. Abaixo você confere o vídeo sobre o mesmo [...]

  10. Daniel says:

    Nao to conseguindo baixar o codigo do Failover… tem como vereficar?

  11. Andreano Lanusse says:

    Olha no diretório Failover, está lá

  12. Daniel says:

    nao consegui achar o diretorio, o arquivo que baixei foi este 27391_datasnap_2010_samples

  13. Daniel says:

    Obrigado baixei de volta e consegui.

  14. leandro says:

    Andreano gostaria de agradecer por disponibilizar os materiais, já me ajudou bastante. Só tive um problema para conectar ao arquivo DSSERVERLOG.IB disponibilizado com os exemplos. Ocorre um erro na conexao (o mesmo nao ocorre ao conectar no employee.IB): unsupported on-disk structure for file XXXXX; found 13; support 12. Acredito que eu esteja usando uma versão antiga do interbase, estou certo? Você poderia disponibilizar o script de criação desse bd? Dessa forma que eu poderia criar 0 bd aqui e rodar sua aplicação exemplo sem erros. Muito obrigado. Abraço

  15. Andreano Lanusse says:

    Oi Leandro,

    Fico contente em saber que os exemplos estão ajudando. Sobre o erro é porque eu criei esse banco com IB 2009, faz o seguinte, deleta este arquivo, o servidor irá criá-lo de novo.

  16. Larissa Franco says:

    Bom dia Andreano!
    Estou aqui para parabenizálo, por este interessante artigo!
    Gostaria de saber como faço para implementar o LoadBalance, procurei mas não achei.
    Você saberia me informar aonde encontro vídeo-aulas ou algum site que ensine como fazer?

    Agradeço a atenção,
    Larissa.

  17. Marcelo says:

    Oi Andreano,

    Você poderia dar uma explicação detalhada de como o Delphi 2010 faz o balanceamento de carga? Quais critérios são adotados na hora de decidir qual o melhor servidor a aplicação cliente deve conectar? É analisado sobrecarga de CPU, memória, HD, número de conexões…
    Obrigado.

  18. Marcelo says:

    Oi Andreano,

    Usar uma conexão HTTP não seria mais lento do que uma conexão TCP/IP ao servidor Failover? Porque o Delphi 2010 optou por uma solução HTTP de Failover e não por uma solução TCP/IP de forma mais simples?

    Obrigado.

  19. Andreano Lanusse says:

    Oi Marcelo,

    HTTP é uma camada que corre sobre TCP/IP, isso o torno um pouco mais lento do que puro TCP. No exemplo que disponibilizei veja que a conexão do servidor de Failover para o servidor DataSnap é feita através de TCP/IP. Usamos HTTP como solução, pois todo o gerenciamento de sessão já está implementado no protocolo, facilita o roteamento das sessões, liberação de porta em firewall, etc… Lembre-se que nossa conexão DataSnap através de HTTP é bem leve e tem uma ótima performance.

  20. Andreano Lanusse says:

    Oi Larissa,

    Obrigado por acessar o meu blog.

    O vídeo está no post, por alguma razão ele sumiu mas agora está de volta. Além disso o código fonte do exemplo está disponível no link ao final do post. Com esse material você poderá reusar ou montar o seu próprio servidor Failover.

  21. Andreano Lanusse says:

    Marcelo,

    O controle de como fazer o balanceamento depende da sua implementação, no exemplo que mostrei eu redireciono a conexão quando um erro acontece na comunicação.

    O mesmo irá se aplicar a balanceamento de carga, você descobrindo o nível de utilização de cada servidor irá decidir para onde enviar a conexão. O nível de utilização pode ser baseado nos critérios que você mencionou, mas geralmente se utiliza CPU e memória.

  22. Diego says:

    Ola Andreano.
    Estou começando a implementar o Failover em minha aplicação. Porém, estou me dando o seguinte erro : “Protocol http can be used after an adequate instance of TDBXCommunicationLayer is registered with TDBXCommunicationLayerFactory.” quando estou dando um connect := true.
    Eu apenas arrastei a conexao do DataExplorer. Falta mais alguma coisa ???
    Obrigado.

  23. Andreano Lanusse says:

    Oi Diego,

    A comunicação do cliente tem que usar HTTP, verifica no seu SQLConnection se assim está.

  24. Diego says:

    o SQLConnection esta da seguinte forma:

    ;DelegateConnection=DBXTraceConnection
    drivername=DataSnap
    HostName=pc140
    Port=8080
    CommunicationProtocol=http

    OBS: qdo da um active pelo compomente, ele conecta normal, em tempo de projeto, porem em tempo de execução ele apresenta o erro postado anterior.

  25. Diego says:

    Andreano, consegui fazer funcionar, estava faltando a declaração de uma unit. Agora uma dúvida, o servidor Failover fica em cada maquina cliente, ou na mesma maquina servidor datasnap ?

  26. Rodrigo Rodrigues says:

    Olá Andreado, no DataSnap existe uma forma de conectarmos a um servidor datasnap através de roteador? ou seja, sem especificar o IP da conexão?

    alguma coisa que capturassemos as informações de conexão com o Host.

    Muito parecido como esse programas de acesso remoto faz, como o teamviewer, logmein, EchoVNC etc.

Deixe uma resposta

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>