Temos um servidor web apache na frente do Tomcat hospedado no EC2, o tipo de instância é muito grande com 34 GB de memória.
Nosso aplicativo lida com muitos serviços da web externos e temos um serviço da web externo muito ruim, que leva quase 300 segundos para responder às solicitações durante o horário de pico.
Durante o horário de pico, o servidor engasga com apenas cerca de 300 processos httpd. ps -ef | grep httpd | wc -l = 300
Pesquisei no Google e encontrei inúmeras sugestões, mas nada parece funcionar. A seguir, algumas configurações que fiz, que são obtidas diretamente dos recursos online.
Aumentei os limites de conexão máxima e clientes máximos no apache e no tomcat. Aqui estão os detalhes da configuração:
//apache
<IfModule prefork.c>
StartServers 100
MinSpareServers 10
MaxSpareServers 10
ServerLimit 50000
MaxClients 50000
MaxRequestsPerChild 2000
</IfModule>
// tomcat
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="600000"
redirectPort="8443"
enableLookups="false" maxThreads="1500"
compressableMimeType="text/html,text/xml,text/plain,text/css,application/x-javascript,text/vnd.wap.wml,text/vnd.wap.wmlscript,application/xhtml+xml,application/xml-dtd,application/xslt+xml"
compression="on"/>
//Sysctl.conf
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
fs.file-max = 5049800
vm.min_free_kbytes = 204800
vm.page-cluster = 20
vm.swappiness = 90
net.ipv4.tcp_rfc1337=1
net.ipv4.tcp_max_orphans = 65536
net.ipv4.ip_local_port_range = 5000 65000
net.core.somaxconn = 1024
Eu tenho tentado inúmeras sugestões, mas em vão .. como consertar isso? Tenho certeza que o servidor m2xlarge deve atender a mais de 300 solicitações, provavelmente eu posso estar errado com a minha configuração ..
O servidor engasga somente durante o horário de pico e quando há 300 solicitações simultâneas aguardando a resposta do serviço da web [300 segundos atrasado].
Eu estava apenas monitorando as conexões TCP com o netstat
Encontrei cerca de 1000 conexões no estado TIME_WAIT, não faço ideia do que isso significaria em termos de desempenho, tenho certeza que deve estar aumentando o problema.
Saída do TOP
8902 root 25 0 19.6g 3.0g 12m S 3.3 8.8 13:35.77 java
24907 membase 25 0 753m 634m 2528 S 2.7 1.8 285:18.88 beam.smp
24999 membase 15 0 266m 121m 3160 S 0.7 0.3 51:30.37 memcached
27578 apache 15 0 230m 6300 1536 S 0.7 0.0 0:00.03 httpd
28551 root 15 0 11124 1492 892 R 0.3 0.0 0:00.25 top
Output of free -m
total used free shared buffers cached
35007 8470 26536 0 1 61
8407 26599
15999 15 15984
output of iostat
avg-cpu: %user %nice %system %iowait %steal %idle
26.21 0.00 0.48 0.13 0.02 73.15
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda1 14.36 4.77 329.37 9005402 622367592
sdb 0.00 0.00 0.00 1210 48
Também no horário de pico, existem cerca de 10 a 15k conexões tcp ao servidor membase [local]
ALGUNS ERROS NO MODJK LOG, espero que isso jogue alguma luz sobre o assunto.
[Wed Jul 11 14:39:10.853 2012] [8365:46912560456400] [error] ajp_send_request::jk_ajp_common.c (1630): (tom2) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=110)
[Wed Jul 11 14:39:18.627 2012] [8322:46912560456400] [error] ajp_send_request::jk_ajp_common.c (1630): (tom2) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=110)
[Wed Jul 11 14:39:21.358 2012] [8351:46912560456400] [error] ajp_get_reply::jk_ajp_common.c (2118): (tom1) Tomcat is down or refused connection. No response has been sent to the client (yet)
[Wed Jul 11 14:39:22.640 2012] [8348:46912560456400] [error] ajp_get_reply::jk_ajp_common.c (2118): (tom1) Tomcat is down or refused connection. No response has been sent to the client (yet)
~
Worker.properties
workers.tomcat_home=/usr/local/tomcat/
worker.list=loadbalancer
worker.tom1.port=8009
worker.tom1.host=localhost
worker.tom1.type=ajp13
worker.tom1.socket_keepalive=True
worker.tom1.connection_pool_timeout=600
worker.tom2.port=8109
worker.tom2.host=localhost
worker.tom2.type=ajp13
worker.tom2.socket_keepalive=True
worker.tom2.connection_pool_timeout=600
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=tom1,tom2
worker.loadbalancer.sticky_session=True
worker.tom1.lbfactor=1
worker.tom1.socket_timeout=600
worker.tom2.lbfactor=1
worker.tom2.socket_timeout=600
// Resolvido
obrigado por todas as suas sugestões valiosas .. perdi as configurações maxThreads para o conector AJP 1.3 .. Agora tudo parece estar sob controle.
Eu também começaria a olhar para servidores baseados mesmo como o nginx.
fonte
top
durante esses tempos? Que talfree -m
? E por últimoiostat
?Respostas:
Você aumentou maxThreads no AJP 1.3 Connector na porta 8009?
fonte
Considere a possibilidade de configurar um servidor da Web de proxy assíncrono como
nginx
oulighttpd
na frente do Apache. O Apache exibe conteúdo de forma síncrona, para que os funcionários sejam bloqueados até que os clientes façam o download completo do conteúdo gerado (mais detalhes aqui ). A configuração de um proxy assíncrono (sem bloqueio) geralmente melhora drasticamente a situação (eu costumava diminuir o número de trabalhadores do Apache em execução simultânea de 30 para 3-5, usandonginx
como proxy de front-end).fonte
Eu suspeito que seu problema está no tomcat e não no apache, pelos logs que você mostrou de qualquer maneira. Quando você recebe o 'erro 110' ao tentar se conectar novamente ao tomcat, isso indica que há uma fila de conexões aguardando para serem atendidas, que não cabem mais na configuração da lista de pendências de escuta do soquete de escuta no tomcat.
Se eu tivesse que adivinhar, suspeitaria que a grande maioria das solicitações HTTP quando o servidor está "bloqueando" está bloqueada, aguardando que algo volte do tomcat. Aposto que se você tentasse buscar algum conteúdo estático que é servido diretamente pelo apache (em vez de ser procurado pelo tomcat), isso funcionaria mesmo quando estivesse "sufocando" normalmente.
Infelizmente, não estou familiarizado com o tomcat, mas existe uma maneira de manipular as configurações de simultaneidade disso?
Ah, e você também pode considerar a possibilidade de que os serviços de rede externa limitem o número de conexões que ele está fazendo para você em até 300, portanto, não faz diferença a quantidade de manipulação de simultaneidade que você está fazendo na sua frente. se praticamente todas as conexões feitas forem baseadas em uma resposta externa de serviços da web.
Em um de seus comentários, você mencionou que os dados ficam obsoletos após 2 minutos. Sugiro que você armazene em cache a resposta que você recebe deste serviço por dois minutos para reduzir a quantidade de conexões simultâneas que você está dirigindo para o serviço da web externo.
fonte
A primeira etapa para solucionar isso é habilitar o mod_status do Apache e estudar seu relatório - até que você faça isso, na verdade você está andando cegamente. Isso não é justo. ;-)
A segunda coisa a mencionar (eu não gosto de receber respostas para perguntas que não estava fazendo, mas ...) está usando servidores front-ends mais eficientes e especiais como
nginx
.Além disso, não é exatamente o
restart
apache, ou apenasgraceful
ly recarregado -lo? :)fonte
mod_status
é seu amigo, de qualquer maneira. :)Para qualquer tipo de implantação empresarial, o MPM pré-fork é praticamente a pior escolha que você pode fazer: consome recursos como os negócios de ninguém, e reiniciar threads leva para SEMPRE em comparação com outros MPMs.
Pelo menos, mude para o MPM de trabalho (apache 2.2 ou superior) ou - melhor ainda - atualize para a versão estável atual 2.4.2 com seu evento padrão MPM.
Ambos lidam facilmente com milhares de conexões simultâneas com muito pouca sobrecarga.
fonte
Eu sei que é uma história antiga, mas tenho 2 comentários.
Há um limite codificado para a Diretiva ServerLimit . http://httpd.apache.org/docs/2.2/mod/mpm_common.html#serverlimit, você verá que é no máximo 20000 / 200K.
Segundo, aparentemente, o nodybo mencionou que definir esses 2 para um é uma péssima idéia :
significa que você reutiliza o timewait cedo, adivinhe? o servidor pode conversar com o cliente errado sob carga pesada.
Encontrei um artigo muito bom explicando isso, mas - é francês ;-) http://vincent.bernat.im/fr/blog/2014-tcp-time-wait-state-linux.html
fonte
O ferro grande não é o caminho para dimensionar o serviço da Web, você está apenas movendo os gargalos. Mas, mesmo com tanta memória, suspeito que 50000 conexões estão promovendo o que o sistema é capaz, principalmente se:
Seria útil se você explicasse o que quer dizer com "o servidor engasga".
Também é muito estranho ter um limite tão alto para conexões, mas um limite muito baixo para histerese (servidores sobressalentes mín. / Máx.).
Embora a extração de erros que você forneceu não mostre o indicador 'muitos arquivos abertos', eu começaria examinando o número de descritores de arquivos abertos e as configurações ulimit.
fonte
Talvez o usuário do Apache esteja ficando sem identificadores de arquivos permitidos? Você não os mencionou na sua postagem. Quantos manipuladores de arquivos o Apache atualmente tem?
fonte
É mais como um comentário, mas, como não posso, tenho menos reputação. Me deparei com um problema exatamente semelhante ao do @john titus.
Tornamos o conector AJP
MaxThreads
próximo ao nosso limite do Apache Thread para resolver o problema.Para monitorar isso, procuramos a
SYN_SENT
ajuda do status da porta netstat com o comando netstat em nossa porta AJP.netstat -an | grep :8102 | grep SYN_SENT | wc -l
Isso caiu para 0, que sempre foi um grande número antes do limite do MaxThread definido no AJP Connector.
fonte