HAPROXY balanceando JBOSS
Este post estava encostado há algum tempo, finalmente consegui tempo para publicá-lo.
Há alguns meses um leitor me pediu ajuda com o HAPROXY, ele disse que havia visto em minha wiki alguns exemplos de uso, mas queria algo mais focado no JBOSS, este leitor tinha uma necessidade específica e resolvi ajudá-lo, mesmo não sendo especialista e não conhecendo a fundo a ferramenta.
Abaixo segue o roteiro completo de nossos estudos e descobertas.
1. Sobre o HAPROXY
O HAProxy é uma solução - opensource - que oferece recursos de High Availbility, Load Balance e PROXY para aplicações baseadas em TCP e HTTP. Ele foi particularmente desenhado e pensado para web sites com grande carga que necessitam de persistência ou processamentos específicos na camada de aplicação (layer7). Ele suporta milhares de conexões em hardwares muito modestos. É uma ferramenta fácil de instalar, configurar, operar e principalmente fácil de integrar aos ambientes e arquiteturas existentes.
Existem casos documentados de ambientes HAPROXY atendendo demandas que geravam de 3 a 6 Gibabits de tráfego - por segundo. Existem testes de laboratório feitos pelo criador da ferramenta demonstram que ele chegou a atender cerca de 106 mil requisições HTTP por segundo, e encaminhar (HTTP FORWARD) cerca de 40 mil requisições por segundo para backends internos.
Mas quem usa o HAPROXY?
AMAZON, TWITTER, REDDIT, FARMVILLE, GITHUB, TUMBLR, DISQUS, FEDORA, REDHAT CLOUD, STACKOVERFLOW.
* Dados retirados de http://haproxy.1wt.eu/they-use-it.html
2. HAPROXY
2.1 Instalando
A instalação é bastante simples, vou mostrar como instalar no Debian e CentOS.
No Debian
aptitude install haproxy
No CentOS
yum install haproxy
Se preferir compile - recomendado - a última versão disponível, basta fazer o download dos sources no site do haproxy.
2.2 Cenário
O leitor queria balancear uma aplicação de ensino a distância, tipo moodle, porém a ferramenta foi escrita em Java. Em seu ambiente ele tinha dois servidores bem robustos rodando JBOSS, e um servidor mais modesto em standby, estes por sua vez, sustentavam a aplicação de EAD.
2.3 Configuração
O arquivo de configuração tem o nome de haproxy.cfg, ele normalmente está no diretório /etc/haproxy.
A configuração proposta foi a seguinte:
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice info
maxconn 25000 # numero maximo de conexoes que ele vai atender
user haproxy
group haproxy
daemon
nbproc 2 # numero de processadores
defaults
contimeout 5000
clitimeout 50000
srvtimeout 50000
retries 3
listen sistema 0.0.0.0:80
log global
mode http
option httplog
option dontlognull
option redispatch
option forwardfor
option httpclose
option forceclose
option persist
stats enable
stats auth admin:proinfo
stats uri /haproxy_stats
stats realm HAProxy\ Statistics
cookie SERVERID insert indirect nocache
balance roundrobin
server app01 10.1.1.1:8080 cookie A weight 1 maxconn 5000 inter 2s rise 2 fall 3 check
server app02 10.1.1.2:8080 cookie B weight 1 maxconn 5000 inter 2s rise 2 fall 3 check
server app03 10.1.1.3:8080 cookie B weight 1 maxconn 5000 inter 2s rise 2 fall 3 check backup
2.3.1 section global
A seção global do arquivo de configurações define algumas configurações globais, são elas:
log => configurações de log
maxconn => número máximo global de conexões que ele vai atender
user => usuário que vai rodar o serviço
group => grupo
daemon => forma de funcionamento, no caso standalone
nbproc => número de processadores
2.3.2 section defaults
A seção defaults define algumas configurações padrão para os listeners e backends.
contimeout => tempo máximo que o servidor aguarda para um conexão ser estabelecida
clitimeout => tempo máximo de inatividade no lado do cliente
srvtimeout => tempo máximo de inatividade no lado do servidor
retries => qts vezes o clt ainda deve tentar se conectar após uma falha
2.3.3 section listen
Está seção define as portas que o HAPROXY vai abrir e escutar, além disto é aqui que fazemos todas as configurações de balanceamento. Abaixo a explicação de cada parâmetro:
log => confs de log, no caso confs do global
mode http => modo de funcionamento (http ou tcp )
option httplog => habilita log http
option dontlognull => não loga conexões de checagem, ajuda a evitar log poluído
option redispatch => limpar o cookie caso o backend caia
option forwardfor => para empurrar o ip do cliente para o backend
option httpclose => ajuda a fechar conexões que já deveriam ter sido encerradas
option forceclose => ajuda a fechar conexões que já deveriam ter sido encerradas
option persist => habilitando persistentica
stats enable => habilita estatísticas
stats auth admin:password => usuário/senha para acessar stats
stats uri /haproxy_stats => url das estatísticas
stats realm HAProxy\ Statistics => realm de autenticação
cookie SERVERID insert indirect nocache => injeta cookie na conexao
balance roundrobin => tipo de balanceamento
2.3.3.1 parâmetro cookie
SERVERID => nome do cookie que será inserido, caso necessário
indirect => não insere cookie se o cliente já tiver um cookie válido
insert => insere um cookie para controle de persistência de sessão caso seja necessário
nocache => se cookie for inserido (insert) orienta a não fazer cache
2.3.3.2 parâmetro balancer e server
Veja abaixo que a configuração de balanceamento possui três backends com diversos parâmetros definidos para eles.
server sistema_01 10.1.1.1:8080 cookie A weight 1 maxconn 5000 inter 2s rise 2 fall 3 check
server sistema_02 10.1.1.2:8080 cookie B weight 1 maxconn 5000 inter 2s rise 2 fall 3 check
server sistema_03 10.1.1.3:8080 cookie C weight 1 maxconn 5000 inter 2s rise 2 fall 3 check backup
Vamos entender agora para que serve cada parâmetro:
check => verifica se a porta está aberta no servidor do pool
cookie => nome do cookie que será injetado no lado do cliente
backup => essa maquina só vai entrar se uma instância do pool estiver fora
inter => significa que ele fará checagens no backend a cada 2 segundos
rise => significa que a maquina só volta para o pool se tiver 2 checagens positivas
fall => significa que a maquina só sairá do pool se tiver pelo menos 3 checagens negativas
maxconn => número máximo de conexões que a instância deve receber
weight => peso que a instância terá no pool, quando maior mais conexões vão para ele
2.4 Estatísticas
Para acessar as estatísticas habilitadas na configuração proposta, basta apontar seu navegador para o endereço abaixo:
http://ip-do-servidor-haproxy/haproxy_stats
Através desta ferramenta de estatística, você terá dados completos sobre o balanceamento.
* Vai pedir o usuário e senha definidos na configuração.
2.5 Entendendo a configuração
Abaixo explico em 6 passos rápidos a configuração criada.
- A configuração option persist força o acesso a um servidor do balanceamento que esteja demorando a responder, em caso de servidores que atendem muitas requisições isso é importante, as vezes ele não está fora só está lento.
- Estamos injetando um cookie (cookie SERVERID insert indirect nocache) com nome SERVERID para organizar o balanceamento e manter a persistência de sessão. Quando um cliente chega, o haproxy injeta um cookie SERVERID=A/B/C para ele, assim quando ele voltar a conectar, vai trazer a informação do cookie (SERVERID=A) e a partir disto cair no mesmo servidor que ele iniciou a conexão, assim ele mantém a persistência na sessão.
- É muito bom ter a persistência configurada, porém se uma máquina do balanceamento sair do ar, alguns clientes não irão conseguir fazer flush no cookie, com isso eles ficarão perdidos, com o option REDISPATCH isso é resolvido, o cookie é resetado caso o backend tenha sido removido do balanceamento e a partir daí a requisição vai para o próximo servidor disponível.
- O option forwardfor é utilizado para empurrar o IP do cliente para o backend ao invés de empurrar o IP do HAPROXY, isso é bom quando queremos gerar estatísticas usando ferramentas como AWSTATS, estas ferramentas normalmente fazem leitura dos logs dos backends.
- O option httpclose e option forceclose são utilizados para fechar conexões. Algumas vezes alguns servidores ao receberem o httpclose, mesmo assim ainda mantém a conexão aberta com o cliente, deixando ela cair por timeout, isso pode ocasionar centenas e as vezes milhares de conexões desnecessárias esperando timeout, esses dois parâmetros resolvem isto, fechando a conexão assim que o servidor terminar de responder.
- Configuramos 3 backends, 2 ativos e um em standby (backup), esse último só entrará no balanceamento caso um dos backends principais seja removido por alguma razão, essa máquina é mais modesta, por isto está em modo backup.
3. Amarrando as pontas
Segundo o leitor, até hoje o balanceamento está funcionando redondinho, e ele por sinal está bastante feliz.
Tive que ler bastante para ajudá-lo na configuração, isso me ajudou a desenferrujar no HAPROXY, e olha que havia um bom tempo em que eu não usava ele para algo, finalmente surgiu uma boa oportunidade.
O HAPROXY ainda tem centenas de recursos para conhecer, alguns muito interessantes para PROXY e LOAD BALANCER, ele tem suporte a ACLs para redirecionamentos especiais, podemos construir regras fantásticas usando ACLs.
Outra questão sensacional é o balanceamento TCP, posso virtualmente criar um balanceamento na camada 4 utilizando apenas esta ferramenta, com isso posso balancear IMAP, POP, SMTP e qualquer outra aplicação que atenda clientes utilizando uma porta TCP.
Logo podemos dizer que com o HAPROXY você pode construir seu próprio SWITCH de conteúdo.
Se quiser criar um ambiente com HA para seu HAPROXY recomendo o uso do KEEPALIVED. Acesse o site do Andy Leonard para ler um bom tutorial sobre esse assunto.
Eu já vi casos de uso do NGINX para fazer proxy reverso e o HAPROXY para balanceamento, afinal ele é especializado nisto.
Já vi cenários com NGINX + HAPROXY + VARNISH (PROXY => BALANCEAMENTO => CACHE).
A grande vantagem do HAPROXY na minha opinião é que ele é uma ferramenta especializada em balanceamento, diferente de outras ferramentas que também fazem balanceamento, mas não são especializadas nisto. O HAPROXY é incrivelmente performatico e usa poucos recursos do servidor (MEM/PROC) para fazer seu trabalho.
Eu particularmente gosto muito desta ferramenta e das possibilidades que ela me oferece, recomendo de olhos fechados.
* Caso alguém que conheça melhor a ferramenta tenha visto algo errado, por favor nos avise e ajude melhorar este estudo, como eu já disse, sou um admirador da ferramenta mas não um grande conhecedor :)