Problema VRAPTOR e SPRING - Consumo CPU

5 respostas
J

Boa noite pessoal. Implementamos o VRAPTOR em nossa empresa e estamos utilizando em todos os sistemas, porém a pouco em um sistema
com grande quantidade de acessos e fluxo de dados começamos a ter alguns problemas relativos a grande quantidade do uso da CPU, onde
o mesmo costuma a chegar a 300% no periodo de maior fluxo do site, assim o site fica lento e acaba caindo depois de um tempo.

OS: Linux ubuntu 10.04
JAVA: JRockit 1.6
Server: Tomcat 7
Framework: vrpator 3.4.1, spring 3.1

Com isso começamos a analisar os fatores que poderiam estar causando esses problemas, realizamos todas as configurações possíveis no tomcat
e no apache até chegarmos a analisar no JProfile e encontrarmos um overflow de carregamento na classe:

  • org.springframework.web.context.ConfigurableWebApplicationContext.getBean()

Simulando a grande quantidade de acessos percemos que a mesma inicia com um tempo bom e ao simular acessos o tempo aumenta até parar o sistema o tomcat.

Estamos em um ambiente onde utilizamos o Vraptor para a camada controller e para a camada de serviço abstraimos o mesmo utilizando
o Spring Framework para realizar as injeções de dependência, e as configurações são realizadas no arquivo application-context.xml. Ex:

<bean id="orderStatusService" class="br.com.xxx.module.order.service.impl.OrderStatusServiceImpl"> <property name="repository" ref="orderStatusDAO"/> </bean>

Utilizamos o @Inject também para algumas classes onde que nos permite e facilita a não precisar configurar o XML. Nos Controladores utilizamos o VRaptor sem nenhuma modificação apenas criação de Interceptors para atender necessidades específicas.

Estamos tentando descobrir o que poderia estar causando esse grande consumo de CPU e o seu amento significativo, alguém já passou por isso ou pode nos
ajudar?

5 Respostas

boneazul

Qual a ultima instrução que o log do tomcat dispara antes de cair ??

Lucas_Cavalcanti

o spring consome bastante CPU mesmo, pq ele faz bem mais do que dar new nos objetos…

se vc não estiver usando nenhum módulo específico do spring (tipo o transaction ou o security), você poderia mudar para o Guice, que é bem mais rápido.

você conseguiu rodar o JProfiler com o sistema rodando de verdade?

assim vc consegue ter uma idéia melhor do que está acontecendo com o uso real da aplicação. Só não faça isso em horários de pico, pq o jprofiler deixa o servidor bem mais lento que o normal.

G

Antes de mais nada é importante analisar os parametros de configuração do Tomcat, inicialização de JVM, etc. Em um projeto que participei tinhamos muito consumo de CPU devido a configuração errada nos parametros da JVM, que fazia GC muito seguido.

J

Fala Pessoal Primeiro gostaria de agradecer a ajuda de todos.

Em relação aos logs o servidor cai e não demonstra nenhum log, infelizmente.

Estamos sim analisando o JProfiler no ambiente de testes espelhado no de produção, onde os mesmos problemas ocorrem :frowning:

Em relação aos parametros de inicialização utilizamos somente:

Para o JROCKIT
CATALINA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms2048m -Xmx2048m"

Estou realizando também a sugestao do lucas e trocando o spring para o guice para fazer uma comparacao, porem tenho um duvida, no spring nos usavamos em um dos metodos do service a anotacao @Async no envio de email. para que o spring executasse esse metodo isoladamente, alguem teria uma sugestao pra fazer isso agora com o guice?

Está bem complicado resolver esse problema.

Lucas_Cavalcanti

se for só no envio de emails, vc pode fazer na mão, não é mto difícil (java 6):

@Component
@ApplicationScoped
public class EnviadorDeEmailsAssincrono implements EnviadorDeEmail {
    private final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

    public void envia(final Email email) {
         executor.execute(new Runnable() {
               public void run() {
                     //envia o email de verdade
               }
         });
    }

}

o 10, 20, e 30 são respectivamente, número mínimo e máximo de threads simultâneas, e duração máxima de uma execução (no caso em segundos, mas vc pode mudar a TimeUnit)

talvez seja legal colocar um método @PreDestroy que faz um executor.shutdown() tb.

Criado 21 de junho de 2012
Ultima resposta 21 de jun. de 2012
Respostas 5
Participantes 4