Eu tenho um aplicativo da Web Spring Boot 1.2.7.RELEASE (com o Tomcat integrado) que precisa lidar com um pico de carga muito alto, conexões de ~ 10k em 4 a 5 minutos em um servidor (na verdade, há um cluster de servidores, mas esta é a carga que um nó verá).
É muito, muito lento. Se eu acertar com JMeter com 1.000 threads em 10 segundos, mas apenas um simples pedido GET para a página de login Thymeleaf - nada mais - a resposta média em breve subirá mais de 13 segundos. A página é apenas um formulário de login, usando Thymeleaf.
Isso está sendo executado em uma VM com RHEL7, 32 GB de RAM (com o heap da JVM configurado para usar 28 GB) e 4 núcleos de CPU. Há muita potência aqui, mas estou lutando para que ele responda sob carga.
Como teste, em um esforço para reduzir o número de soquetes e threads, eu comentei dois links na página para css:
<HEAD>
<!-- Other meta stuff omitted -->
<!-- I commented out these next two lines -->
<link rel="stylesheet" href="css/index.css"/>
<link href="css/gridset.css" rel="stylesheet"/>
</HEAD>
Quando fiz exatamente o mesmo teste de carga, obtive uma resposta média de 277 ms! Se eu colocar de volta, a lentidão retorna.
Portanto, sem exagero, a resposta para o mesmo teste passou de 13 segundos para menos de 0,3 segundos.
Eu tentei trazer o css em linha, mas o Spring lança todos os tipos de erros tentando analisá-lo. O Validador do W3C mostra que ambos os arquivos contêm muitos erros.
Alguém está trabalhando para corrigir os erros no css, mas estou me perguntando qual é a causa da lentidão. É o fato de que o CSS está quebrado ou é o fato de que ele está sendo servido pelo Tomcat da área estática? Não terei CSS válido para testar novamente por vários dias e estou sob a ameaça para fazer isso funcionar.
Eu acertei com o firebug, e a página de login única é carregada em 437ms. O primeiro arquivo index.css é carregado em 158ms e o arquivo gridset.css em 53ms. Existem então 3 imagens que totalizam 205ms. O tamanho total das imagens é 19kb.
Vou postar um dump de discussão abaixo. Isso foi gerado pela New Relic.
Eu encontrei algumas informações sobre o Tomcat sendo lento para servir conteúdo estático, mas eu não posso imaginar que isso é lento, e outras pessoas dizem que uma versão recente do Tomcat faz, assim como o httpd.
Sou principalmente um desenvolvedor, então qualquer ajuda para consertar isso é muito apreciada, obrigado!
75% java.lang.Thread.run() :745 70% org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run() :61
70% java.util.concurrent.ThreadPoolExecutor$Worker.run() :617
70% java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor.Worker) :1127,1142
69% java.util.concurrent.ThreadPoolExecutor.getTask() :1066
69% org.apache.tomcat.util.threads.TaskQueue.poll(long, java.util.concurrent.TimeUnit) :31
69% org.apache.tomcat.util.threads.TaskQueue.poll(long, java.util.concurrent.TimeUnit) :85
69% java.util.concurrent.LinkedBlockingQueue.poll(long, java.util.concurrent.TimeUnit) :462,474,467
69% java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(long) :2069,2083,2078
69% java.util.concurrent.locks.LockSupport.parkNanos(java.lang.Object, long) :215
69% sun.misc.Unsafe.park(boolean, long) :native