section{Cluster Tomcat}

O Tomcat \cite{tomcat} é um servidor de aplicações Java, \textit{Java Servlet} e \textit{JavaServer Pages} (JSP). O objetivo de um servidor de aplicações é disponibilizar uma plataforma abstraindo do desenvolvedor de \textit{software} algumas das complexidades de um sistema computacional. O servidor de aplicações responde a questões comuns à todas as aplicações, como segurança, alta disponibilidade, balanceamento de carga e tolerância à falhas.

Ele é distribuído como \textit{software livre} e desenvolvido dentro do projeto Apache Jakarta, que é oficialmente endossado pela Sun como a Implementação de Referência (RI) para as tecnologias \textit{Java Servlet} e \textit{JavaServer Pages} (JSP). O Tomcat é, suficientemente, robusto e eficiente o  para ser utilizado em ambientes de produção.

Tecnicamente o Tomcat é um \textit{container} Web, cobrindo parte da especificação J2EE e servindo de container para tecnologias como \textit{Servlet} e JSP, e tecnologias de apoio como \textit{JNDI Resources} e \textit{JDBC DataSources}. O Tomcat tem a capacidade de atuar também como servidor web/HTTP, ou pode funcionar integrado a um servidor Web dedicado, como o Apache httpd ou o Microsoft IIS.

A partir da versão 5, Tomcat passou a dispor de escalabilidade horizontal (capacidade de atender ao aumento de requisições de usuários através do aumento do número de servidores físicos) e alta disponibilidade (capacidade de suportar falhas de \textit{hardware} ou \textit{software} e manter o sistema a maior tempo possível ativo) por meio de suporte nativo a \textit{clustering}.

O uso da metodologia de cluster permite que várias instâncias de Tomcat estejam disponíveis para o usuário como um servidor único, permitindo que a carga das requisições sejam distribuídas entre essas várias instâncias (balanceamento de carga), sem o uso de recursos computacionais especializados, fazendo que o sistema possa manipular uma quantidade muito maior de requisições antes de uma possível sobrecarga. O sistema construído também se vale de alta disponibilidade, caso um dos nós que compõem o sistema caia, as requisições de usuários continuam a ser tratadas de maneira transparente.

\begin{figure}[!htb]
\centering
\includegraphics[scale=0.4]{imagens/tomcatvisaogeral.png}
\caption{Visão geral de um cluster Tomcat}
\label{fig:tomcatgeral}
\end{figure}

O modelo básico para clusterização em Tomcat envolve o uso de duas camadas adicionais (\ref{fig:tomcatgeral}), uma camada responsável pelo balanceamento de carga e outra camada que cuidará do compartilhamento de informações, como sessões e outras variáveis de estado, entre os servidores Tomcat

\subsection{Balanceamento de carga}

Há várias opções que podem ser usadas na camada de balanceamento de carga em um cluster Tomcat, todas elas visando distribuir as requisições de clientes entre os servidores para melhorar a performance do sistema. Entre essas opções serão aqui destacadas:

\begin{enumerate}[.]
\item DNS \textit{Round-robin}.

\item Hardware especializado.

\item Apache mod\_jk/mod\_jk2.

\item Balanceamento de carga via \textit{software}, como LVS (\textit{switch} de camada 4).
\end{enumerate}

\textbf{DNS \textit{Round-robin}}\\

DNS \textit{Round-robin} é a solução mais simples de ser implementada, usando uma lista de IP's dos servidores Tomcat, percorrendo-a de maneira circular enviando cada nova requisição para um IP Tomcat diferente. Muito embora seja uma solução prática de ser implementada, ela não leva em consideração a carga da máquina para a qual uma requisição será enviada, não apresenta vantagens em relação a tolerância a falhas, já que não toma conhecimento de quais máquinas estão ativas, podendo enviar conexões para máquinas inativas, entre outros reveses.

\begin{figure}[!htb]
\centering
\includegraphics[scale=0.5]{imagens/dnstomcat.png}
\caption{Balanceamento de carga via DNS Round-Robin}
\label{fig:dnstomcat}
\end{figure}

Em servidores DNS configurados para prestar este tipo de serviço, um endereço (ex. www.seudominio.com) é resolvido para os IP's dos servidores que hospedam as instâncias de Tomcat. Quando um cliente requisita uma requisição, o servidor DNS escolhe um dos IP's e o passa para o cliente.

\textbf{\textit{Hardware} especializado}

Geralmente, \textit{hardware} especializado para balanceamento de carga, também conhecido como roteador de camada 4/7, é um dispositivo físico que redireciona conexões para um conjunto de máquinas em uma rede interna. A decisão para o balanceamento é baseada na análise de uma série de fatores como carga do processador, conexões ativas no servidor, entre outros. Isso minimiza a sobrecarga dos servidores além disponibilizar os serviços hospedados nestas máquinas através de um único IP, mapeando as conexões para os IP's internos dos servidores.

Entre as vantagens do uso deste tipo de solução para balanceamento de carga em clusters Tomcat em relação ao uso de DNS \textit{Round-robin} simples são:

\begin{enumerate}[.]
\item Balanceamento de carga mais otimizado, já que fatores como carga de processador e número de conexões ativas são levadas em consideração.

\item Conexões dos clientes não serão enviadas para máquinas que não possam atende-las.
\end{enumerate}

As principais desvantagens são o custo destes dispositivos, a relativa complexidade de configuração e o fato de constituirem um ponto único de falha.

\textbf{mod\_jk}\\

O Apache e seu módulo \textbf{mod\_jk2} podem ser usados para:

\begin{enumerate}[.]
\item Distribuir conexões entre várias instâncias de Tomcat.

\item Detectar falha em instâncias, evitando o envio de requisições a servidores Tomcat que não estejam respondendo.

\item Caso uma instância deixe de responder, mod\_jk2 verifica periodicamente se ela voltou, caso a instância volte a responder ela é posta junto com as outras instâncias em funcionamento, voltando a receber requisições.
\end{enumerate}

\begin{figure}[!htb]
\centering
\includegraphics[scale=0.2]{imagens/tomcatmodjk.png}
\caption{Balanceamento de carga via Apache mod\_jk}
\label{fig:tomcatmodjk}
\end{figure}

As requisições são distribuídas com mod\_jk2 através de um algoritmo de \textit{Round-robin} podendo ser levado em conta um fator de carga (peso associado a cada instância que regula a prioridade com a qual recebem conexões).

mod\_jk2 trabalha também com sessões afins (\textit{sticky sessions}) que assegura que todas as requisições com mesma sessão serão tratadas pelo mesmo nó Tomcat. A desvantagem desde método é que caso uma instância deixe de funcionar, a sessão associada a ela será perdida.

\textbf{Balanceamento de carga via \textit{software}}

Entre as soluções usadas para balanceamento de carga via \textit{software}, uma das mais conhecidas é o LVS. Classificado como um roteador de camada 4, trata-se de modificações incluídas no kernel Linux usadas para redirecionar conexões TCP de maneira transparente para o usuário.

De maneira geral, funciona como o balanceamento feito com \textit{hardware} especializado. Uma máquina com o sistema operacional Linux (conhecida no jargão LVS como Director) possui o IP que será acessado pelos clientes. O Director, usando seus algoritmos de escalonamento, decide para qual máquina a conexão será redirecionada. Qualquer serviço TCP pode ser redirecionado, incluindo requisições a máquinas que componham um cluster Tomcat.

O LVS mantêm algumas informações sobre os servidores (como número de conexões ativas) para o processo de decisão do balanceamento e também não envia conexões a um servidor que não esteja ativo.

\subsection{Compartilhamento de sessões}

As soluções para balanceamento de carga resolvem o problema da distribuição das requisições dos clientes entre os nós que compõem o sistema. A outra camada mostrada na figura \ref{fig:tomcatgeral}, serve a outro propósito, assegurar que sessões e outras informações não sejam perdidas caso o servidor Tomcat,que as manipulavam, caia.

Na camada de compartilhamento, mostrada na figura \ref{fig:tomcatgeral}, podem ser usado alguns tipos de \textit{back-ends}, cada qual com suas funcionalidades. O compartilhamento de informações nesta camada podem assegurar que a perda de conectividade de um dos servidores Tomcat que compõem o cluster seja manipulada de forma a não gerar transtorno para o usuário.

\subsubsection{\textit{Sticky sessions} em compartilhamento de sessões}

Neste tipo de configuração, o balanceador de carga mod\_jk2 assegura que as requisições de uma mesma sessão serão sempre tratadas pela mesma instância Tomcat. Este tipo de configuração é conveniente a muitos cenários de produção, apresentando as seguintes características:

\begin{enumerate}[.]
\item Escalabilidade para a aplicação provida por algoritmo \textit{Round-robin}, que cria novas sessões no próximo nó livre na fila round-robin.

\item Simplicidade de implantação e manutenção.

\item Nenhum tipo de configuração adicional ou sobrecarga de recurso.
\end{enumerate}

Apesar das vantagens, as sessões são perdidas se o servidor que as manipula cai.

\subsubsection{\textit{Stiky sessions} com gerenciamento de sessões persistentes e armazenamento compartilhado}

A partir da versão 5, Tomcat passou a dispor de um sistema de gerenciamento de sessões persistentes. O propósito deste mecanismo é manter as sessões ativas caso haja desligamento e reinício de servidor. Para tanto, as sessões são gravadas em disco ou em SGBD, o que garante a manutenção da informação mesmo que o servidor seja desligado. Esse mecanismo, a princípio, não foi desenvolvido para atender demanda de implementação em cluster, entretanto sistemas de arquivos compartilhados ou SGBD essas informações estarão disponíveis para todas as instâncias de Tomcat que compõem o sistema.

A figura ilustra o funcionamento deste mecanismo. Um diretório para armazenamento das sessões é acessível a todos os servidores Tomcat através de mecanismos como SMB, NFS, OCFS2, assim as sessões podem ser criadas ou modificadas por todas as instâncias. Isto também garante uma menor perda de informação em caso de problemas com o sistema e procedimentos de recuperação.