domingo, 4 de janeiro de 2009

Alta Disponibilidade de DataSources no JBoss

Neste quick-tip, irei apresentar como aplicar um recurso interessante do JBoss sobre alta disponibilidade de datasources. O recurso se refere a capacidade do pool de conexões poder identificar quando um determinado servidor de banco de dados está fora do ar, e automaticamente, sem que as aplicações que fazem uso do mesmo saibam da falha, ele direcione as conexões das aplicações (e suas respectivas sessões) para o próximo servidor SGBD disponível.

Entendendo o que é alta disponibilidade

Antes de mergulharmos nos detalhes técnicos sobre o recurso, é importante entender claramente o que é alta disponibilidade, o que isso acarreta e o que esperar deste recurso. Alta disponibilidade é um requisito de qualidade (requisito não funcional) que diz respeito a capacidade que um sistema provê sobre estar disponivel mesmo quando uma falha aconteça aos componentes principais do sistema.

O fruto deste tipo de solução é o uso de redundância, ou seja, colocar disponivel mais de uma instância de todo hardware e software necessário para a solução funcionar. A função da cópia redundante é assumir o controle do sistema quando a cópia oficial (Master Copy) falhar por qualquer razão. Neste caso, recomenda-se que o hardware tenha as mesmas caracteristicas (configuração) do hardware oficial.

Como a redundância implica em custo, é necessário escolher qual ponto do sistema realmente vale a pena ou é crucial a sua alta disponibilidade. Nem sempre, todo o sistema pode estar totalmente redundante e alguns pontos podem ter tempos de contingência para recuperação de falhas, outro requisito de qualidade muito comum. Escolhido qual é o componente do sistema que sofrerá redundância, é necessário usar mecanismos arquiteturais que possibilitem a troca de versão e contexto do hardware, sem impacto na execução da solução.

A unica coisa que este recurso deve prover é a capacidade de execução do sistema, perante falhas do hardware. Não é recomendado, nem prudente que você espere que o recurso vá garantir maior eficência da execução das tarefas do sistema, nem muito menos que o sistema fique mais rápido que o normal. Esta caracteristica é de outro requisito de qualidade, e é normalmente implementado com mecanismos de balanceamento de carga e cluster.

Entendido a diferença, é importante deixar claro o que se espera da solução, uma vez que as expectativas sobre alta disponibilidade são facilmente confundidas com balanceamento de carga e cluster, não sobre a solução em si, mas o que esperar dele. Já vi muitas pessoas com visões errôneas sobre este recurso.

Aplicando High Availability no JBoss

O servidor de aplicação JBoss possui uma infra-estrutura muito interessante para alta disponibilidade de recursos, em especial, recursos como pool de conexões, filas JMS e motores de jobs. A mágica sobre o recurso é o uso do JNDI na plataforma Java. Todo recurso no JEE é recuperado através de JNDI. Sendo assim, é prudente se esperar que o objeto que vai para o cliente, é potencialmente um proxy.

A chave para qualquer solução de alta disponibilidade (e balanceamento de carga) é colocar um Proxy entre o cliente da solução e a porção do sistema que provê os recursos. Através do proxy, pode-se obter um nível de indireção que favorece a troca de contexto e endereço do recurso físico. No caso de JEE, como os recursos são retornados para o cliente via JNDI, este canal de recuperação de recursos (Factory) pode ser usado para substituir o recurso real por um proxy.

É com base nesta idéia que o suporte do JBoss é fundamentado. A boa noticia é que nada em termos de implementação precisa ser mudado, o programador irá realizar o uso das conexões da mesma forma que sempre fez. O que muda é a declaração do recurso dentro do servidor de aplicação. No JBoss, para se criar um pool de conexões que ofereça recursos de tolerância a falhas e alta disponibilidade, basta criar um datasource como mostrado na listagem abaixo.

Repare que a listagem mostra uma declaração de um pool de conexões local (não XA) não muito diferente do que se já está acostumado a fazer. A grande sacada é a tag de declaração do datasource. Repare que a declaração começa com 'ha-local-tx-datasource' ao invés de 'local-tx-datasource'. Com isso, o JBoss irá inferir que se deseja criar um pool de alta disponibilidade.

Lido a declaração da tag, o JBoss irá procurar pelo caracter usado para separar os diversos endereços de conexão com os servidores de banco de dados, através da tag 'url-delimiter'. No exemplo mostrado, o caracter usado é o '|'. Neste caso, o JBoss irá ler a tag 'connection-url' e irá recuperar os diversos endereços de conexão separados por '|'. Repare que foram disponibilizados dois endereços, um apontando para o banco de dados 'gest_esc_a' e outro para 'gest_esc_b'. O banco A será usado como cópia mestre da solução, e se ele falhar, o banco de dados B assume o controle.

O controle sobre as conexões é feito de forma transparente para as aplicações. Quando o banco falha por qualquer razão, abre-se uma nova conexão no segundo servidor e o resto acontece naturalmente. Interessante heim?

Boas Arquiteturas!

1 comentários:

Feroz disse...

Excelente dica !

Aproveitando o ensejo, uma vez ví em seu blog, um post em que você falava de uma ferramenta para visualizar os logs do Jboss de uma forma remota e prática.

Você ainda lembra qual era ??