Cluster de Tomcat’s

 

Um cluster de tomcat são dois um mais tomcat’s  em que são hospedadas a mesma aplicação Java. A principal função do cluster de tomcat é realizar replicação de sessões abertas em cada tomcat do cluster, assim cada tomcat conterá suas sessões e seus atributos, assim como  os atributos e sessões dos demais tomcat’s. Cada tomcat do cluster é chamado de nó.

Com o cluster de tomcat’s  é possível obter a alta disponibilidade, de modo que se um nó do cluster falhar, as requisições vindas para este nó, serão desviadas para  outro nó ativo. Tudo isso sem que o usuário perceba pois sua sessão estará ativa nos outros nós do cluster.

A Figura abaixo mostra a arquitetura do cluster de tomcat’s:

 

Tomcat Cluster

 


Configuração do Cluster de Tomcat

 

Levarei em consideração que você já tenha duas instancias do tomcat, o apache e o java instalados no seu servidor. Segue abaixo a descrição do ambiente que será utilizado nesse pequeno projeto, vale lembrar que é apenas um projeto de teste:

-Duas instancias de máquinas virtuais no virtualbox;

- Cada VM com 512MB de RAM e 8GB de HD;

- Cada VM com o sistema Operacional CentOS 5.7 (Final);

Obs.: essa configuração poderá ser realizada em qualquer servidor Linux.

 

Requisitos:

 

Para realizar a replicação de sessões entre os nós do cluster alguns pontos devem ser verificados:

- todos os atributos de sessão devem implementar java.io.Serializable;

- Ter no arquivo web.xml da aplicação o atributo <distributable/> ou definir um propriedade na configuração do contexto da aplicação no arquivo server.xml;

- configurar o balanceador de carga com a opção sticky session ativa, para manter as requisições de um mesmo usuário do sistema indo para um mesmo nó do cluster, exceto quando falhar este nó.

 

Iniciando a Configuração:

 

A Configuração dos tomcat’s para o cluster é realizada a partir da edição do arquivo server.xml, localizado na pasta conf (<diretório do tomcat>/conf/server.xml) de cada tomcat. O que deve ser feito é descomentar toda a tag cluster e acrescentar a configuração adequando os parâmetros ao ambiente de hospedagem. Logo abaixo a configuração do cluster:

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"

                 channelSendOptions="8">

 

          <Manager className="org.apache.catalina.ha.session.DeltaManager"

                   expireSessionsOnShutdown="false"

                   notifyListenersOnReplication="true"/>

 

          <Channel className="org.apache.catalina.tribes.group.GroupChannel">

            <Membership className="org.apache.catalina.tribes.membership.McastService"

                        address="228.0.0.4"

                        port="45564"

                        frequency="500"

                        dropTime="3000"/>

            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"

                      address="auto"

                      port="4000"

                      autoBind="100"

                      selectorTimeout="5000"

                      maxThreads="6"/>

 

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">

              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>

            </Sender>

            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>

            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>

          </Channel>

 

          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"

                 filter=""/>

          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

 

          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"

                    tempDir="/tmp/war-temp/"

                    deployDir="/tmp/war-deploy/"

                    watchDir="/tmp/war-listen/"

                    watchEnabled="false"/>

 

          <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>

          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>

        </Cluster>  

 

Em cada tomcat temos a mesma tag cluster com uma pequena diferença na configuração:

Tag Menbership

Tag Receiver

Tomcat A

Tomcat B

Tomcat A

Tomcat B

address=”224.0.0.4”

address=”224.0.0.4”

address=”auto”

address=”auto”

port=”45564”

port=”45564”

port=”4000”

port=”4000”

 

Agora temos que identificar cada nó no mesmo arquivo “server.xml”:

No tomcat A e no tomcat B será preciso fazer algumas alterações para os nós poderem se comunicar:

TOMCAT A

Onde tem:

Coloque:

<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">

<Engine name="Catalina" defaultHost="localhost" jvmRoute=”node01”>

 

TOMCAT B

Onde tem:

Coloque:

<Server port="8005" shutdown="SHUTDOWN">

<Server port="9005" shutdown="SHUTDOWN">

<Connector port="8080" ...

<Connector port="9080"…

<Connector port="8006" protocol="AJP/1.3" redirectPort="8443" />

<Connector port="9006" protocol="AJP/1.3" redirectPort="8443" />

<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">

<Engine name="Catalina" defaultHost="localhost" jvmRoute=”node02”>

OBS.: As alterações estão destacadas em negrito, porém essas alterações são um exemplo de configuração não necessariamente terá que utilizar estes mesmo valores pode ser feito com outros valores.

Depois de fazer essas configurações, basta só iniciar os tomcat’s que os mesmos começarão a replicar suas sessões, ou seja, começarão a trabalhar em cluster.

Para iniciar os tomcats basta entrar no diretório Bin/ dentro de cada tomcat e executar o seguinte comando:

#sh startup.sh

 

Balanceamento de Carga

 

É um serviço que é capaz de encaminhar requisições para vários servidores dentro de um cluster,  de modo que cada nó do cluster não fique sobrecarregado, garantindo assim a utilização nivelada de todos os recursos computacionais dentro do cluster.

Neste projeto o apache será o responsável pelo balanceamento da carga entre dois tomcat’s. O Apache irá receber as requisições vinda dos clientes e de acordo com a quantidade de requisições enviadas a cada tomcat, o mesmo irá transferir para cada um deles.

A Figura abaixo mostra a arquitetura do cluster de tomcat’s com balanceamento de carga:

Cluster Tomcat e Load Balance

 

Configurando o Balanceador de Carga

 

Como foi falado nos posts anteriores, o responsável pelo balanceamento de carga será o apache.  Para isso o apache utiliza o mod_proxy e o mod_proxy_balancer. Com o mod_proxy o apache trabalha como um proxy FTP, http e ssl. Já o mod_proxy_balancer provê um serviço de balanceamento de carga para protocolos HTTP, FTP e AJP13. O mod_proxy_balancer depende do uso do mod_proxy.

Atualmente existem dois métodos de balanceamento de carga:

- Por quantidades de requisições onde cada nó do cluster irá receber uma requisição por vez de modo em que nenhum dos nós fique sobrecarregado.

- Por tráfego, onde o balanceador dedica um nó do cluster para a requisição que for trafegar maior quantidade de informações enquanto que as demais requisições serão enviadas para os outros servidores.

 

Iniciando a configuração

 

O cenário onde será feito a configuração do cluster será descrito logo abaixo:

- Ip do Servidor= 192.168.56.101

- Aplicação que será utilizada neste exemplo será um sistema para pedir almoço que foi desenvolvido na empresa que eu trabalho.  O Sistema é jBroca

A configuração do balanceador de carga será feita no arquivo de configuração do Apache “httpd.conf”. No CentOS arquivo de configuração do apache fica dentro do diretório “/etc/httpd/conf/httpd.conf”.

Dentro do arquivo httpd.conf insira este trecho no final do arquivo:

<VirtualHost 192.168.56.101:80>

ServerName 192.168.56.101

ProxyRequests Off

 

<Proxy 192.168.56:80>

Order deny,allow

Allow from all

</Proxy>

ProxyPass /teste balancer://balancer lbmethod=byrequests stickysession=JSESSIONID nofailover=off

ProxyPassReverse /teste http://192.168.56.101:8080/jbroca

ProxyPassReverse /teste http://192.168.56.101:8081/jbroca

 

<Proxy balancer://balancer>

BalancerMember http://192.168.56.101:8080/jbroca      route=node01 loadfactor=1

BalancerMember http://192.168.56.101:8081/jbroca      route=node02 loadfactor=1

</Proxy>

<Location /balancer-manager>

setHandler balancer-manager

Order Deny,Allow

Deny from all

Allow from 192.168.56.101

</Location>

</VirtualHost>

Neste trecho temos a configuração de um virtual host que será responsável pelo recebimento das requisições destinadas a url 192.168.56.101/jbroca. Segue abaixo a descrição de cada item desta configuração:

- ServerName: determina o nome do virtual host, neste caso o 192.168.56.101/jbroca

-ProxyRequest off: determina que o apache não será utilizado como um servidor Proxy ou um reverse Proxy.

- ProxyPass /teste balancer://balancer lbmethod=byrequests stickysession=JSESSIONID nofailover=off: qualquer requisição destinada ao context /teste será utilizado o balanceador de carga balancer para atender as requisições.

- lbmethod=byrequests: é onde define o tipo de balanceamento de carga, onde neste caso o balanceamento de carga é por requisição.

- stickysession=JSESSIONID : define que o apache irá direcionar os pedidos de uma mesma seção para o mesmo servidor.

- nofailover=off: define que todos os servidores dentro cluster serão capazes de superar a falha algum servidor do cluster que se tornar inativo, o apache desviará as requisições deste servidor  para outro servidor.

As opções abaixo são configurações utilizadas para corrigir as respostas vindas dos servidores no cluster que são balanceados, baseando na requisição vinda do cliente:

ProxyPassReverse /jbroca http://192.168.56.101:8080/jbroca

ProxyPassReverse /jbroca http://192.168.56.101:8081/jbroca

Agora é onde declaramos ao balanceador de carga os membros do cluster com suas respectivas características:

<Proxy balancer://balancer>

BalancerMember http://192.168.56.101:8080/jbroca        route=node01 loadfactor=1

BalancerMember http://192.168.56.101:8081/jbroca       route=node02 loadfactor=1

</Proxy>

A ultima opção habilita o gerenciamento do balanceador de carga para os navegadores do domínio: 192.168.56.101. Para visualizar o balancer-manager no navegador basta digitar:http://192.168.56.101/balancer-manager

<Location /balancer-manager>

setHandler balancer-manager

Order Deny,Allow

Deny from all

Allow from 192.168.56.101

</Location>

Com isto, o apache está configurado para realizar o balanceamento de carga, encaminhando as requisições para os dois servidores dentro do cluster.

 Para testar se toda configuração está correta, inicie os tomcat’s e inicie o apache se iniciar corretamente os servidores seu cluster está funcionando e basta acessar no navegador para verificar se o balanceador está funcionando corretamente. No exemplo citado basta acessar: http://192.168.56.101/jbroca

Acesse em diferentes navegadores e verifique se realmente o balanceador está direcionando as requisições para cada servidor. Neste exemplo que foi utilizado será na barra de endereço mostra que as requisições estão sendo balanceadas:

http://192.168.56.101/jbroca/autenticarUsuario.do;jsessionid=9225E01A70F0A90B2283244B2CF554D3.node01

http://192.168.56.101/jbroca/autenticarUsuario.do;jsessionid=4B2BF75B6B2F99EAB791D512E52AC626.node02

O endereço retornado mostra as requisições divididas nos dois tomcat’s do cluster. O balancer-manager também mostra se as requisições estão sendo balanceadas.

 Finalizamos aqui, espero que todos tenham conseguido compreender o que eu tinha para passar para vocês. A aplicação não será disponibilizada por ser uma aplicação utilizada somente na empresa que eu trabalho, então desenvolvam a aplicação de vocês e testem as aplicações rodando em cluster. Qualquer dúvida é só entrar em contato que eu estarei disponível para a ajuda-los, muito obrigado a todos.