Mostrando postagens com marcador tomcat. Mostrar todas as postagens
Mostrando postagens com marcador tomcat. Mostrar todas as postagens

sexta-feira, 25 de julho de 2008

JVM Tuning

Buenas!

Devido ao longo tempo sem postar algo realmente decente e técnico, este post vai ser sobre o que estou fazendo atualmente, que é instalando e configurando os servidores de produção aqui da empresa juntamente com uma outra pessoa.

O nosso ambiente compreende um cluster de Tomcats fazendo Session Replication. Nossos servidores são de arquitetura Intel e do modelo QuadCore (apesar de uma plataforma Sun ser bem mais performática ainda mais com Java), então algumas configurações são específicas para isso e para o nosso modelo de aplicação e talvez não sejam as melhores para o seu caso, mas de qualquer forma gostaria de compartilhar um pouco das coisas que aprendi e que estamos utilizando.

JDK - Porque a versão 6?

Além de ser a última versão, ela é superior a versão 5 em questões de performance, as configurações default da vm já vem otimizadas para uma melhor performance de runtime e um garbage colector mais eficiente.

Esta versão, por ser mais recente, usa de uma maneira mais elevada o poder de multi-processadores ou multi-cores e da grande quantidade de memória existente. Exemplos disso são, o uso do GC em threads paralelas, podendo utilizar até 32 Threads (veja mais na tópico sobre Tuning), usa também do paralelismo para a promoção de objetos do Young para o Old (Permanent) conforme figura abaixo (caso queira aprender mais sobre como funciona o Heap Space do java leia este documento e este documento)JVM Tuning

Como muitos sabem, é possível mudar o comportamento da VM e parametrizar muitas coisas através das VM Options que são passadas na inicialização de um processo.
No nosso caso aqui, utilizamos alguns parâmetros, que vou listar abaixo com uma breve descrição:

[JVM Parameters]
-server - Para simplificar, este parâmetro te da uma melhor performance final do que inicial. Caso sua arquitetura seja 64bits, o server é o default, e para arquiteturas 32bits, o client é o default.
-XX:+UseLargePages - Se o seu SO permite Large Memory Pages habilite esta função e sete também outros parâmetros relacionados a isso. Para saber mais sobre LMP leia este documento.
-XX:+AggressiveOpts - Habilita algumas otimizações de código, que segundo a documentação, é pra estar habilitada como padrão nas versões futuras.
-XX:+UseFastAccessorMethods - Usa versões otimizadas para métodos get de tipos primitivos.
-XX:+UseParallelGC - Habilita o GC para abrir várias thread e atuar paralelamente.
-XX:ParallelGCThreads=6 - Número de thread que serão abertas para GC. Por default é aberto uma Thread para cada processador existente.
-XX:+UseParNewGC - Igual ao parâmetro UseParallelGC, porém para a área Young do Heap.
-XX:+UseTLAB - Usa Thread-Local para alocação de objetos

[MEMORY]
-Xms 512M - Parâmetro de memória que define o mínimo de memória para a aplicação.
-Xmx 8G - Parâmetro de memória que define o máximo de memória para a aplicação

[YOUNG]
-XX:NewSize=256M - Tamanho mínimo para a área Young do Heap.
-XX:MaxNewSize=1G - Tamanho máximo para a área Young do Heap.

[OLD]
-XX:PermSize=512M - Tamanho mínimo da área de objetos permanentes em memória.
-XX:MaxPermSize=2G - Tamanho máximo da área de objetos permanentes em memória.

Obs: não sete os valores máximos maiores que o -Xmx.

Para ver oturos parâmetros para VM veja esta página.
Para ver alguns exemplos de tuning de aplicações veja este link.
Leia também a FAQ sobre GC.

Ferramentas para Monitoramento de Aplicações

Segue abaixo algumas ferramentas que podem te ajudar a entender melhor sua aplicação e te ajudar a chegar a valores para os parâmetros. Existem muitas outras, outra hora comento sobre algumas mais específicas, mas comentei sobre essas apenas porque já vem com o próprio JDK, e vc as encontra em $JAVA_HOME/bin.

  • jps - Mostra os processos Java que estão rodando na máquina.
  • jinfo - Mostra informações sobre o processo java que está rodando, como bibliotecas que ele está usando, parametros de inicialização, parâmetros gerais da VM como aquelas que aparecem em System.getEnv().
  • jmap - Mostra informações sobre o uso de memória por uma aplicação, uso de cada divisão da Heap como a Young, Old, Tenure, Perm, etc.
  • jsadebugd - Este processo se junta ao processo passado como parâmetro e adiciona propriedades de debug ao processo em questão.
  • jconsole - JConsole é uma ferramenta visual que monitora e mostra várias informações sobre um processo, como uso de memória, número de threads, processamento, etc.
  • jstat - Coleta e loga informações estatísticas sobre performance.

Considerações

Conforme dito acima essas configurações são específicas para cada caso, então se precisar de ajuda sobre algumas configurações para um caso específico comente aqui, que responderei assim qeu possível.
Como tuning é um trabalho constante, a monitoração e o profiling são coisas extremamente importantes para que você consiga entender sua aplicação e definir o que usar e o que não usar.
Conforme for otimizando a nossa aplicação estarei fazendo update neste post, ou escrevendo novos posts se for o caso.
Enfim, espero que isso possa ajudar algumas pessoas, e com certeza vai me ajudar futuramente como documentação.

terça-feira, 24 de julho de 2007

Configurando Virtual Host e Default Context no Tomcat

Bom, este post veio porque ontem ajudei um grande amigo meu com um probleminha neste aspecto. Queira aproveitar a oportunidade para deixar um grande abraço aqui pra ele, Daniel Kühl Lima, um dos únicos LPI3 do Brasil.

Normalmente quando você publica um servidor com um tomcat servindo uma aplicação, o que costuma-se fazer é simplesmente publicar a aplicação e passar a url para o usuário, por exemplo: www.meudominio.com.br:8080/aplicacao, e o usuário para acessar sua aplicação precisa digitar a url como consta ali, caso ele digita até o / ele irá cair naquela página default do tomcat, com links pra o Administrador e Manager.
Isso é beeem feio. Existe algumas maneiras de se fazer isso de uma forma mais "descente".
Primeiro, para melhorar, o usuário não precisa saber qual a porta para acessar a aplicação, então passar 8080 na url, é feio. Então o mais comum para arrumar isso é levantar o Tomcat com a porta 80. Para isso, é necessário alterar o arquivo [tomcatdir]/conf/server.xml trocando a porta na seguinte linha (normalmente está ~ pela linha 76):

< port="8080" maxhttpheadersize="8192">
trocar a linha pela
< port="80" maxhttpheadersize="8192">
Com isso resolvemos o problema de o usuário ter que digitar a porta 8080 na url. Porém, se o usuário digitar somente o seu domínio ele ainda acessará a página default do tomcat.
O que muita gente faz para corrigir isso, é instalar um Apache + Conector para Tomcat (para saber como configurar ver a documentação dos Connectors da Apache), e assim, ele configura para que o apache intermedie requisições para o tomcat, para que quando for acessado o raiz (www.meudominio.com.br) ele redirecione para a aplicação e pronto, o usuário não precisa mais saber qual o nome da aplicação.

Isso funciona. Mas para que ter que configurar mais uma coisa para acessar o tomcat, mais um possível ponto de erro!?
O que muita gente não sabe é que o próprio Tomcat tem suporte a Virtual Hosts.
Por default, o tomcat já vem com um Host configurado, que é justamente o raiz da aplicação, que é aquele host que está no arquivo server.xml.
< name="localhost" appbase="webapps" unpackwars="true" autodeploy="true" xmlvalidation="false" xmlnamespaceaware="false">

< !-- UM MONTE DE COMENTÁRIO AQUI-- >

< /host >

Para configurar então o tomcat para que assim que o usuário digitar a url do seu domínio ela acesse diretamente sua aplicação, você pode apenas definir o Default Context.

< name="localhost" appbase="webapps" unpackwars="true" autodeploy="true" xmlvalidation="false" xmlnamespaceaware="false">

< path="" docbase="aplicacao">

< /Host >

O path="" significa que será o context default, ou seja, assim que o usuário acessar o raiz de seu domínio, ele acessará a aplicação que você definiu no docBase.
Isto funciona para a maioria dos casos onde você tem apenas uma aplicação no servidor. Mas se você tiver um servidor que serve para vários domínios, você então precisará configurar Virtual Hosts, assim como era feito no Apache, quem administra servidores, sabe o que, e como fazer isso. Então, para fazer isso no Tomcat, basta você adicionar um novo Host, parecido com o do exemplo acima, porém, passando o domínio como name do host. Ex:

< name="www.meudominio2.com" appbase="/caminho/aplicacoes">
< path="" docbase="aplicacao2">
< /Host >
Agora, este novo host, você pode definir um context default ou não, isso depende da sua configuração. Caso você tenha multiplos domínios e apenas um servidor, basta ir adicionando eles a este arquivo. Lembre-se que todos os elementos Host ficam dentro do elemento Engine.

Nota importante:
Fiz alguns testes, e o tomcat se comportou de maneiras distintas em algumas versões diferentes. O que notei foi que o / tanto no appBase do Host, quanto no docBase do Context, faziam diferença. Então, caso não esteja conseguindo configurar, tente remover, ou inserir as barras tanto no início do caminho, quanto no final.

Bom, é isso, hoje não estou muito inspirado para escrever, então, eu sei que o post ficou com um português meio ruinzinho... Mas, sobretudo, espero ter ajudado alguém. Qualquer dúvida poste ai que eu tento responder.

[Update]
Para fazer isto no tomcat 6 mudou um pouquinho na parte de deixar o tomcat responder na porta 80 (primeira parte deste post). Mas não tem segredo, procure um "Connnector" no mesmo arquivo server.xml que contenha 8080, e altere para a porta 80 =) O resto continua a mesma coisa. Valeu.