terça-feira, 13 de setembro de 2016

Load balancer com WildFly 10

Esse passo a passo mostra como montar um ambiente com um Apache HTTP Server como loadbalancer e vários WildFly 10 atrás utilizando sempre o modo standalone.

Bom, trabalho com JBoss/WIldFly desde a versão 3 e já montei ambientes load balancer e cluster em mais de 20 ambientes... Esse mês montei novamente utilizando o WildFly 10 para um cliente que estou dando consultoria.

Antes de mais nada agradeço a todos do JBug Brasil. Sem a galera desse grupo eu não saberia nem iniciar o WildFly :) Entrem lá, recomendo!

O ambiente será assim:




Standalone ou domain?
Resolvi usar o modo standalone pois acredito que o modo domain adiciona um pouco mais de complexidade que não é necessária para ambientes com poucos servidores WildFly....

o domain serve apenas para centralizar as configurações em uma máquina só... caso queira fazer usando o modo domain, basta seguir esse tutorial e depois alterar para o modo domain....


Load balancer e/ou cluster

Aqui mostro apenas o como fazer um Load Balancer... não mostro como fazer um cluster... mas em muitos (talvez na maioria) dos ambientes, o cluster não é necessário....

O Load balancer serve para permitir escalabilidade... então atrás do Apache vai ter vários WildFly e você pode adicionar mais caso necessário (caso aumente o número de usuários por exemplo)

O Load balancer serve para redundância... se cair um WildFly, outro WildFly vai assumir....

"Tá Adriano, então pra que serve o cluster?"

O cluster serve para permitir o compartilhamento de dados de sessão.. por exemplo... no load balancer se vc estiver logado e de repente o WildFly cair, outro WildFly vai assumir, mas você voltará para a tela de login e terá q fazer login de novo... pois dados de sessão não são compartilhados no load balancer....

Para permitir que o usuário continue logado, você teria que ter um cluster...

Como os WildFly não vão cair o tempo inteiro... e se quando cair não for um problema tão grande o usuário ter q fazer login de novo... você não precisa de cluster....

Se você quiser fazer um cluster tudo bem.... não é muuuito dificil, é só seguir esse tutorial e depois alterar mais algumas coisinhas para implementar o cluster, mas não vou mostrar isso neste post...

Ahhh... E caso você esteja usando Amazon ou Digital Ocean... fazer um cluster vai ser um pouco mais difícil pois eles não permitem multicast (q é como as máquinas do cluster se comunicam) e você teria que fazer isso de outra forma... o q não é tããão simples...

Post passo-a-passo

Talvez (ou não) vc esteja se perguntando:
"Este passo-a-passo é completo e é só seguir que vai dar certo?"

Não! Esse passo-a-passo provavelmente não vai estar 100% claro e talvez falte algum detalhe... Foram anotações que fiz quando estava montando esse ambiente...

Não achei nenhum passo-a-passo mostrando como montar um load balancer com WildFly 10... por isso resolvi postar aqui mesmo que falte algum detalhe...

Até pq quando você for usar talvez vc use alguma versão diferente do que usei ou talvez seja diferente na sua infra ou no seu S.O.

Já montei load balancers e clusters em mais de 20 ambientes... e todas as vezes deu algum problema diferente...

"Tá Adriano, mas se não tá completo então esse post é inútil"

Acredito que é útil sim! talvez vc vai ter alguma dificuldade em algum ponto... aí vc abre um chamado no JBug Brasil e eu e outros caras que são bem legais vamos tentar te ajudar.


Vamos lá!


Você precisará de 3 máquinas:
- maq01: Apache HTTP Server
- maq02: WildFly Server1
- maq03: WildFly Server2

Sistema operacional
Sugiro o uso do sistema operacional RHEL (Red Hat Entrerprise Linux) ou CentOS (que é igual ao RHEL só que da comunidade).
Mas já implantei isso no Ubuntu também.
No Windows deve dar também... mas esse post vai ser todo focado em linux...


Em todas as máquinas faça esses passos:

- Configure a rede conforme desejado:
/etc/init.d/network stop
vi /etc/sysconfig/network-scripts/ifcfg-eth0
vi /etc/sysconfig/network
vi /etc/resolv.conf
/etc/init.d/network start

- Teste se a rede está OK
ping www.google.com
ifconfig


Maq01 - Apache HTTP Server

Documentação complementar:
https://docs.jboss.org/mod_cluster/1.1.0/html/native.config.html
https://httpd.apache.org/docs/2.4/howto/access.html

Apache 2.2
Aqui vou falar como implantar com o Apache 2.2... mais pra baixo comento como é com o Apache 2.4

yum install httpd httpd-devel apr-devel openssl-devel mod_ssl -y

sudo service httpd start


- Acesse no browser de sua máquina e verifique se o Apache HTTP Server está no ar, só acessar pelo ip: http://<ip da maquina>

- Baixe o mod_cluster (sempre utilize a versão mais atual ao invés de usar o comando abaixo, procure em http://mod-cluster.jboss.org/)
wget http://downloads.jboss.org/mod_cluster//1.3.1.Final/linux-x86_64/mod_cluster-1.3.1.Final-linux2-x64-so.tar.gz
tar -zxvf mod_cluster-1.3.1.Final-linux2-x64-so.tar.gz
cp mod_advertise.so /etc/httpd/modules/
cp mod_manager.so /etc/httpd/modules/
cp mod_proxy_cluster.so /etc/httpd/modules/
cp mod_cluster_slotmem.so /etc/httpd/modules/

- Comente a linha do mod_proxy_balancer pois será usado o mod_cluster
cd /etc/httpd/conf.modules.d
vi 00-proxy.conf

- A linha deve ficar assim:
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so


- Crie e adicione o conteúdo do arquivo mod_cluster.conf
cd /etc/httpd/conf.d/
touch mod_cluster.conf
vi mod_cluster.conf

LoadModule cluster_slotmem_module modules/mod_cluster_slotmem.so
LoadModule manager_module modules/mod_manager.so
LoadModule proxy_cluster_module modules/mod_proxy_cluster.so
LoadModule advertise_module modules/mod_advertise.so

MemManagerFile /var/cache/mod_cluster

Maxcontext 100
Maxnode 100
Maxhost 100

<VirtualHost *:80>

<Directory />
Order deny,allow
Allow from all
</Directory>

<Location /mod_cluster_manager>
SetHandler mod_cluster-manager
#Order deny,allow
#Deny from all
#Allow from all
AuthType Basic
AuthName "MCM"
AuthUserFile /etc/modclusterpassword
Require user admin
</Location>

KeepAliveTimeout 60
MaxKeepAliveRequests 0
ServerAdvertise Off
EnableMCPMReceive Off

</VirtualHost>



Apache 2.4
Essa semana instalei esse ambiente no Ubuntu e no Apache 2.4... teve algumas diferenças...

Para fazer isso (Apache 2.4 no Ubuntu) usei esse passo-a-passo:
https://symbiotics.co.za/configure-apache-with-mod_cluster-load-balancer-on-ubuntu/


Se acontecer o erro:

apache2: Syntax error on line 140 of /etc/apache2/apache2.conf:
Syntax error on line 3 of /etc/apache2/mods-enabled/proxy_cluster.load:
Cannot load /usr/lib/apache2/modules/mod_proxy_cluster.so into server:
/usr/lib/apache2/modules/mod_proxy_cluster.so: undefined symbol: ap_proxy_hashfunc



A solução é deixar o arquivo "proxy_cluster.load" dessa forma:

LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule cluster_slotmem_module /usr/lib/apache2/modules/mod_cluster_slotmem.so
LoadModule manager_module /usr/lib/apache2/modules/mod_manager.so
LoadModule advertise_module /usr/lib/apache2/modules/mod_advertise.so
LoadModule proxy_cluster_module /usr/lib/apache2/modules/mod_proxy_cluster.so


Além disso, aconteceu o erro:

[Thu Aug 25 18:01:33.049309 2016] [proxy:warn] [pid 5911:tid [...] [client 177.101.142.200:58291] AH01144: No protocol handler was valid for the URL /systemprops. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.

Ali onde estou carregando os módulos então tive que adicionar a seguinte linha:

LoadModule proxy_ajp_module /usr/lib/apache2/modules/mod_proxy_ajp.so

Mais detalhes em: https://developer.jboss.org/thread/272092. Agradeço ao Ingo e filippe.spolti do JBug Brasil pela ajuda nesse problema.


Além disso, deu o erro:

2016-08-23 19:38:20,417 ERROR [org.jboss.modcluster] (UndertowEventHandlerAdapter - 1) MODCLUSTER000042: Error null sending INFO command to ip-<IP INTERNO DO APACHE>.sa-east-1.compute.internal/<IP INTERNO DO APACHE>:80, configuration will be reset: null


A solução... meu conf do apache estava assim:

<Directory />
     Order deny,allow
     Allow from all
</Directory>

Mas na versão Apache 2.4 tem que ser assim:

<Directory />
    AllowOverride none
    Require all granted
</Directory>

Mais detalhes em: https://developer.jboss.org/thread/272023



- Crie um usuário e senha
htpasswd -c /etc/modclusterpassword admin

- Reinicie o Apache:
sudo service httpd stop
sudo service httpd start

- Teste novamente no browser: http://<ip_da_maquina>

- Teste no browser o mod_cluster: http://<ip_da_maquina>/mod_cluster_manager




Maq02, Maq03

- Instale e configure o Java (Sempre use a versão mais atual)

Aqui está um exemplo de como instalar (no caso Java 7, mas use o 8), mas pode fazer como achar melhor.
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.rpm

rpm -Uvh jdk-7u79-linux-x64.rpm

alternatives --install /usr/bin/java java /usr/java/latest/jre/bin/java 200000
alternatives --install /usr/bin/javaws javaws /usr/java/latest/jre/bin/javaws 200000
alternatives --install /usr/bin/javac javac /usr/java/latest/bin/javac 200000
alternatives --install /usr/bin/jar jar /usr/java/latest/bin/jar 200000


- Instale o WildFly (Sempre baixe a versão mais atual):
Aqui está o 8, mas use o 10 ou superior:

wget http://download.jboss.org/wildfly/8.2.0.Final/wildfly-8.2.0.Final.zip

yum install unzip

unzip wildfly-8.2.0.Final.zip  -d /opt/
ln -s /opt/wildfly-8.2.0.Final /opt/wildfly


- Configure um usuário no linux:
groupadd wildfly
useradd -s /bin/bash -d /home/wildfly -m -g wildfly wildfly
chown -R wildfly:wildfly /opt/wildfly-8.2.0.Final
chown -h wildfly:wildfly /opt/wildfly

sudo vi /etc/sudoers
wildfly ALL=(ALL) NOPASSWD:ALL

passwd wildfly
su wildfly


- Inicie o WildFly rodando o standalone.sh da pasta bin passando como parâmetro o profile full-ha
./standalone.sh -server-config=standalone-full-ha.xml

- Veja no log se não deu erros
vi /opt/wildfly/standalone/log/server.log

- Pare o WildFly


- Adicione as linhas de JAVA_OPTS:
vi /opt/wildfly/bin/standalone.conf
JAVA_OPTS="$JAVA_OPTS -Djboss.bind.address=<IP MAQUINA>"

Ao invés de IP da máquina você pode usar 0.0.0.0 que é mais genérico



- Configure o mod_cluster no WildFly:
- acesse o arquivo standalone-full-ha.xml
- procure o subsystem modcluster e altere o conteúdo dele para:

<mod-cluster-config advertise-socket="modcluster" proxies="apache1" advertise="false" sticky-session="true" load-balancing-group="arquitetura" connector="ajp">
   <dynamic-load-provider>
     <load-metric type="cpu"/>
   </dynamic-load-provider>
</mod-cluster-config>


-dentro do seu socket-binding-group, você deve colocar isso:

<outbound-socket-binding name="apache1">
<remote-destination host="<IP INTERNO DO APACHE>" port="80"/>
</outbound-socket-binding>

Mais sobre isso: https://developer.jboss.org/thread/272022


- Inicie o WildFly
./standalone.sh -server-config=standalone-full-ha.xml


- Faça deploy de uma aplicação de testes
- Faça o deploy da aplicação systemprops jogando o war na pasta deployments do WildFly: https://dl.dropboxusercontent.com/u/8155843/TDC%20Floripa%202015/systemprops.war

Teste o load balancer
1) Acesse via broser a aplicação pelo apache http server: http://<ip_do_apache>/systemprops
2) A aplicação mostrará em qual host você vai estar: arquitetura-1 ou arquitetura-2. Vai depender de onde o loadbalancer te direcionou
3) Vá até a máquina que você foi direcionado (arquitetura-1 por exemplo) e pare o WildFly
4) Acesse a mesma URL e veja que você foi redirecionado para o arquitetura-2, ou seja, o loadbalancer está funcinando
5) Suba novamente o wildfly


Segurança
- Nunca inicie nada como root
- Não deixe acessível na web o servidor onde está o WildFly (configuração de infra). Resumindo, você não pode conseguir pingar o servidor onde está o WildFly, pois só o servidor do Apache deve estar disponível.
- Use SSL
- Permita o acesso ao mod cluster manager apenas na rede interna (melhor opção) ou apenas para um determinado IP. Algo como:
<Location /mod_cluster_manager>
SetHandler mod_cluster-manager
Order deny,allow
Deny from all
Allow from <seu_ip>
AuthType Basic
AuthName "MCM"
AuthUserFile /etc/modclusterpassword
Require user admin
</Location>

Mais sobre segurança em: https://developer.jboss.org/thread/258299


Perfomance
- Com Java 8 já vai aumentar muuuito a performance comparado com versões anteriores..
- o load balancer é bom para performance pois vai distribuir os acessos deixando tudo mais rápido...
- gzip compression no Apache é essencial
- Configure xms e xmx...
- faça testes de desempenho e utilize ferramentas de monitoramento: http://localhost8080.blogspot.com.br/2016/07/monitorar-ambiente-infra-e-jboss-wildfly.html
- Tuning: http://localhost8080.blogspot.com.br/2014/06/tunning-de-aplicacoes-java.html


Integração contínua
Use! :)


Consultoria:
Lembrando que se precisar dou consultorias nesse assunto e também em questões como performance, arquitetura, integração contínua, montagem de ambientes com load balancer e cluster, etc... Só entrar em contato: adriano@localhost8080.com.br


Abraço!
Adriano Schmidt

14 comentários:

  1. Bom dia!

    Excelente tutorial...
    Mas Adriano estou tendo um problema as instâncias não estão sendo replicadas no balancer....ficar o mod_cluster_manager em branco...

    Espero que possa me ajudar se possível

    ResponderExcluir
    Respostas
    1. Opa... abre um chamado no JBug Brasil https://developer.jboss.org/groups/jbug-brasil com todos os detalhes e aí a gente tenta resolver por lá.. essa semana tá corrida pra mim.. mas outras pessoas lá do grupo tmb vou poder ajudar...

      mas algumas dicas... veja se as máquinas (apache e wildfly) se enxergam... use ping e/ou telnet nas portas...

      confira se tá bem certinho o q eu disse no tópico "- Configure o mod_cluster no WildFly:"

      abraço!

      Excluir
  2. Adriano Boa Tarde!

    Vi que você utilizou apache para load balance, e minha pergunta é porque não utilizar o Load Balance do proprio wildfly 10 que é nativo desde sua versão 9? algum motivo especifico?

    ResponderExcluir
    Respostas
    1. Opa.. Não vi ninguém usando o WildFly como load balancer em um ambiente de produção grande... então não quis arriscar visto q esse ambiente q montei era bem importante (muitos produtos, muitos clientes)...

      E o Apache eu uso há bastante tempo, sei que é bom, sei como trabalhar com ele.. Então não vi necessidade de usar outra ferramenta... mais por isso mesmo :)

      Mas no futuro quem sabe eu comece a utilizar o WildFly como loadbalancer...

      abraço!

      Excluir
    2. Estou usando o Load Balance do wildfly 10, em homologação gostei muito dos resultados, mas estou com problema no modo Domain, já estou quase desistindo, problemas ao fazer deploy, tem que fazer diversos reload nos server group, restart.

      Para atualizar a versão da aplicação por exemplo, estou tendo que despublicar, reiniciar o server group, depois publicar. Estou pensando em voltar para standalone, mas não queria voltar para apenas uma processo no standalone.

      Excluir
  3. Como configuro o mod_cluster no WildFly master se for em modo domain?

    ResponderExcluir
    Respostas
    1. Estou subindo o "cluster-example.war" seu, porem não esta continuando a contagem ou seja cluster não esta funcionando, tem ideia do que seria? o apache reconhece as instancias tudo certo.

      Excluir
    2. domain não muda muita coisa... é só ajustar algumas, dá uma estudada em como trabalhar no modo domain, tem bastante coisa na internet... e qualquer coisa abre um tópico no JBug Brasil...

      sobre o cluster... dá uma olhada no início do artigo onde comento sobre a diferença entre load balancer e cluster e digo que não implementei cluster nesse ambiente e o porquê disso.

      abraço!

      Excluir
    3. o problema é que estou um com cluster-ha-singleton, isso que esta matando, a aplicação fica gerando log e deveria gerar somente em um e quando passar para o outro continuar, vou dar um pulo no JBB mesmo, vlw.

      Excluir
  4. Bom dia.
    Gostaria de entender como posso fazer a chamada da aplicação teste no server httpd.
    Estou usando um estrutura de centos 7 com apache 2.4 seguindo a intenção deste tutorial ou seja o balanceamento. Não cluster.
    Fazendo o deploy na máquina 2 e acessando http://:8080/systemprops/ o aplicativo funciona.
    Fazendo o mesmo no httpd não funciona. http:///systemprops/.
    Como fazer a interação do apache com as maq_02 e maq_03?
    O deploy é feito nas duas máquinas?
    Grato.

    ResponderExcluir
    Respostas
    1. opa, desculpa a demora, conseguiu resolver já? acho q vc usou os símbolos de menor e maior aqui no comentário e aí sumiu parte do q vc digitou... enfim, qualquer dúvida posta no JBug Brasil que vemos por lá, abraço!!

      Excluir
  5. senhores,

    Depois de realizado o procedimento para resolver os três erros do apache 2.4, ocorre o erro abaixo

    /usr/lib/apache2/modules/mod_proxy.so: undefined symbol: ap_log_rerror

    Esse erro não é mencionado no artigo, já tentei solucionar, mas não consegui.

    Alguém saberia como solucionar?

    ResponderExcluir
    Respostas
    1. opa, não consigo ver isso agora, mas faz um post lá no JBug Brasil... aí vemos por lá, e tmb mais pessoas vão poder ajudar... abraço!

      Excluir
  6. Ola Adriano, primeiro obrigado pelo post !
    No meu ambiente trabalho com SO Windows, você tem um passo a passo nesse ambiente ?
    Ou sobre o que muda de um SO para outro ?

    ResponderExcluir