terça-feira, 11 de setembro de 2007

Clustering de Jboss - Parte 1

Há algumas semanas atrás eu estava estudando a melhor arquitetura para uma nova aplicação que estamos fazendo. Esta aplicação a princípio deveria por obrigatoriedade rodar clusterizada e distribuida, sendo ela dividida em algumas partes distintas. OK, pensei comigo mesmo, a melhor maneira de fazer isso, é com EJB mesmo, não vai ter como fugir desta vez.

Embora, EJB tenha um certo overhead na parte de lookup e tudo mais, me pareceu a melhor saida no momento mesmo. E analisando melhor a aplicação, a melhor saida ainda, era usar JMS. Devido ao Assincronismo da aplicação. Enfim, para isso tive que estudar certinho como é que o jboss trabalha com o cluster dele, e como fazer funcionar, além de ter que verificar como fazer para que os MDBs e a Fila ficassem clusterizados também.

Então, resolvi postar aqui como fazer tudo isso funcionar, pois a documentação do JBoss não é lá grandes coisas, embora tenha ajudado muito, e o material na internet não é tão abundante assim.


Colocando o Jboss em Cluster


Bom, para utilizar o Jboss em cluster, primeiro é claro você precisa de 2 máquinas ligadas em rede. Da até pra utilizar na mesma para fazer testes, mas da muito empenho, vai por mim, mas se você precisa mesmo utilizar, você precisa trocar TODAS as PORTAS que o Jboss usa, que não são poucas, e para isso precisa garimpar nos milhares de .xml que ele tem (boa sorte =]). Este post pode te ajudar em algumas, porém ele fala de Jboss rodando na configuração default, mas na all que é onde ele já tem as configurações de cluster, tem muito mais portas =).

Então temos, 2 máquinas ligadas em rede e conversando entre si. Simplesmente o que precisamos fazer para colocá-las em Cluster é levantar o jboss de uma máquina e depois de outra, utilizando a configuração all, assim:


run.bat -c all -b 10.77.6.26 (coloque o ip da maquina aqui)


Como pode se notar, o parametro -c indica qual configuração ele vai utilizar, e o parâmetro -b qual será o IP utilizado para identificar a máquina. Caso não seja passado o ip, o default assumido será 127.0.0.1.

Quando "subir" um jboss você notará nas mensagens de log que ele reconheceu que é o primeiro nó do cluster, ou que ele não conseguiu achar nenhum outro nó "no ar" para formar um cluster. Este Jboss estará rodando OK, porém sozinho esperando encontrar algum outro nó para formar o cluster. O próximo passo então, é subir o outro Jboss. Na hora que ele estiver subindo, irá mandar uma mensagem em multicast (ip=228.1.2.3 porta=45566 via UDP) o servidor que já está no ar irá receber esta mensagem, e então inicia o "handshake" e pronto, eles entram em cluster. Tudo isso será mostrado no log do seu jboss, então para isso deixe o cosole aberto e vá vendo as mensagens que vão aparecendo. Irá aparecer algo assim para o primeiro nó:

16:12:40,828 INFO [DefaultPartition] Number of cluster members: 1
16:12:40,828 INFO [DefaultPartition] Other members: 0
16:12:40,828 INFO [DefaultPartition] Fetching state (will wait for 30000 milliseconds):
16:12:40,828 INFO [DefaultPartition] State could not be retrieved (we are the first member in group)

Você pode inclusive ter vários "clusteres" em uma mesma rede, basta para isso mudar o nome do cluster (no arquivo /server/all/deploy/cluster-service.xml), que por default vem com o nome de DefaultPartition. Para verificar se os seus Jboss estão em cluster, além de ver no console que o cluster foi formado, abra o jmx-console e procure por DefaultPartition e clique nele. Lá você encontrará os IPs das máquinas que estão fazendo parte do Cluster na opção
CurrentView.

Vale a pena ressaltar que a comunicação padrão entre os nós do cluster é feita via UDP com Multicast. No meu caso, eu enfrentei problemas para que os nós se achassem, havia muita demora para formar o cluster, e o farm-deployment raras vezes acontecia. Por um problema de Windows (eu li em algum lugar alguma coisa assim), ou do elemento de rede entre os pontos (a nossa rede é uma bosta), não sei bem o que poderia ser, mas não me surpreenderia com nenhuma das possibilidades. O que me deu esta luz, foi justamente este post, ao menos ele estava tendo o mesmo problema que eu. Lembre-se disso caso esteja tendo problemas, isso pode te economizar muito tempo =)

Enfim, o que tive que fazer para funcionar foi alterar o protocolo de UDP para TCP. Fiz isso no arquivo /server/all/deploy/cluster-service.xml). Logo no começo do arquivo existe uma tag chamada < attribute name="PartitionConfig" > , e dentro desta tag tem um outro elemento chamado < Config >. O que vem habilitado (descomentado) por padrão é o UDP, e (graças a Deus) logo abaixo vem a configuração de TCP comentada. Então o que precisa fazer é descomentar um e comentar o outro. E alterar o elemento TCPPING para que ele contenha os IPs dos principais nós do seu cluster, os quais ele acha no começo, depois você pode incluir outros. Então ficaria algo mais ou menos assim:

< tcpping initial_hosts="${jboss.bind.address}[7800],10.77.6.40[7800]"

Sendo que o próprio jboss substituirá jboss.bind.address pelo seu endereço de IP, e o ip que aparece ali, é o IP do outro nó do seu cluster, ou quantos nós você tiver.


Farm Deployment

Outro aspecto interessante do JBoss, é o deployment em farm. Que nada mais é, você precisar apenas se preocupar com um dos nós, e este cuida de replicar o seu estado para os outros. Então, basta apenas você ter sua aplicação publicada em um dos nós e este copiará a todos os outros a aplicação. O mesmo acontece quando você fizer undeploy de uma aplicação em um dos nós.

Para publicar uma aplicação no farm, basta você copiá-la para o diretório /server/all/farm ao invés de copia-la para /server/all/deploy como é o padrão. Caso você copie para o diretório deploy a sua aplicação será publicada apenas na máquina em questão e o farm-deployment não será executado.

Conclusão

Eu não esperava, mas este será o primeiro de uma série de 3 posts (possivelmente), pois senão iria ficar um post muito grande, e eu não gosto de ler posts muito grandes. Então pretendo nos próximos posts falar sobre como configurar sua fila JMS no esquema de High Availability. E ainda uma aplicação de exemplo para testar este esquema. E como deixar seu Jboss mais "tunado" =)

Até!

[edited]
O Paulo Jerônimo tem um screencast bem interessante sobre como rodar mais de um jboss em cluster na mesma máquina.

3 comentários:

Edson L Gonçalez disse...

Oi, legal saber que vc é de Campinas... eu sou de Paulínia e trabalho na Motorola. Seguinte, testei conforme vc explicou e tudo funciona nos seguintes aspectos:

a) O node 1 responde à inicialização do node 2.
b) O node 1 ou 2 faz o farm deploy automático, conforme esperado.
c) Fiz o deploy de um EJB e consigo acessá-lo remotamente tanto chamando pelo IP do node server 1 ou 2.

O caso é que eu gostaria de algum programa ou mecanismo que me permitisse "ver" que o Bean realmente está se comportando de forma clusterizada, vc sabe como fazer isso ? Coloquei uma mensagem de console, mas ela aparece somente no console do host chamado pelo client que invoca o metodo remotamente.

Davi disse...

Muito bom o post , ajudou de verdade

mas a duvida q fica é a seguinte :

o jboss "clusteado" funciona quando uma das redes cair ???

por exemplo se um cair o outro mantem a sessao no ar???

Juliano D. Carniel (jujo) disse...

Davi,

funciona sim. Eu não lembrava exatamente onde que ficava essa confiiguração, dei uma olhada entao na documentação:
http://docs.jboss.org/jbossas/jboss4guide/r4/html/cluster.chapt.html#clustering-http-app

Espero que ajude.
Valeu.