Meu servidor, executando Ubuntu 14/Apache2.4.7, possui um redirecionamento htaccess para forçar todas as solicitações a usar HTTPS. Geralmente, ele responde rapidamente. No entanto, alterei recentemente minha configuração SSL para restringir as cifras usadas a configurações mais modernas para evitar ataques de coração, besta e outras explorações e garantir o uso de métodos de criptografia modernos.
Tenho recebido algumas reclamações ultimamente - que parecem não estar relacionadas a essas mudanças (veja abaixo) - de que minha máquina pode ficar lenta às vezes. Essas reclamações sugerem que pode estar relacionado ao aperto de mão ou ao estabelecimento de uma conexão:
Tenho recebido carregamento lento e intermitente de páginas com várias mensagens de status do navegador, dependendo do navegador usado; tudo no sentido de esperar para estabelecer uma conexão segura.
Escrevi um script PHP que usa cURL para conectar mil vezes. Executei ontem à noite e a lentidão não parecia ser um problema. Tentei me conectar ao https e também ao http e seguir o redirecionamento acima. Todas as solicitações foram concluídas em 3,5 segundos ou menos, sendo que a grande maioria (96-98%) foi concluída em menos de 1,5 segundos.
Executei o mesmo script às 10h30 desta manhã, horário de Brasília, e cerca de 10% das solicitações demoraram mais de 1,5 segundo, com muitas demorando muito mais. Os tempos mais longos foram em torno de 17 segundos.
Minha pesquisa e intuição me dizem que, embora o handshaking https seja mais complexo que as conexões http, esse problema provavelmente pode ser remediado ajustando minha configuração do apache (por exemplo,MaxRequestWorker) configurações. O servidor quase nunca excede uma média de carga de 1,5 ou mais e parece que há bastante memória disponível.
Alguém pode sugerir como posso diminuir o gargalo aqui e quais etapas posso tomar para corrigi-lo? Qualquer ajuda seria muito apreciada.
EDIT: Visitei o canal de IRC #apache e perguntei por lá e o pessoal simpático me chamou a atenção para o fato desse servidor estar empré-garfomodo e MinSpareServers, MaxSpareServers, StartServers e MaxRequestWorkers são todos padrão ou ajustados, mas ainda muito baixos.
Eles foram bastante inflexíveis ao afirmar que um servidor de produção não deveria usar o modo prefork e me encaminharam para alguns links:
- Evento Apache MPM- descreve o modo de evento do Apache
- Executando PHP no Apache httpd- uma lista de opções para executar php no apache
- Uma história sobre openssl_seal(), PHP e Apache2handle- descrição de explorações em php das quais você deve estar ciente
Entendo que a solução de correção para esses problemas de desempenho é provavelmente instalar o Apache para rodar em modo de evento, mas meu site é complexo e usa algumas bifurcações de processo e outras coisas. Espero que, como solução provisória, alguns possam sugerir ajustes paraminSpareServers,maxSpareServers,startServers,maxRequestWorker
EDIT 2: Um detalhamento de uma solicitação lenta típica, conforme relatado por curl_getinfo
função em PHP:
elapsed: 17.6722049713
ssl_verify_result: 0
total_time: 17.671187
namelookup_time: 0.000051
connect_time: 0.065855
pretransfer_time: 16.787012
starttransfer_time: 17.340403
redirect_time: 0.261569
Responder1
Acontece que os pacotes do Ubuntu para instalar o apache e o php7 não parecem oferecer nada além do prefork, querealmente é uma merda.Sendo esse o caso, tive que me contentar com o pré-garfo, que não é a solução ideal, mas até ter mais informações sobre como obter um dosconfigurações recomendadastrabalhando, é minha única opção.
Editei o arquivo /etc/apache2/mods-available/mpm_prefork.conf:
sudo nano /etc/apache2/mods-available/mpm_prefork.conf
E aumentei a configuração MaxRequestWorkers para 300.OBSERVAÇÃOque, para fazer isso, também preciso adicionar uma configuração ServerLimit de 300 ou MaxRequestWorkers é restrito ao valor padrão de ServerLimit, que é 256:
StartServers 5
MinSpareServers 5
MaxSpareServers 10
# changed in response to slow connect/handshaking time complaints
ServerLimit 300
# note this value is constrained by ServerLimit, which defaults to 256
MaxRequestWorkers 300
MaxConnectionsPerChild 0
Essas configurações parecem ter aliviado a lentidão. Usei meu script de teste PHP durante um horário movimentado do dia e todas as solicitações foram concluídas em 3,5 segundos ou menos, a grande maioria concluída em menos de 1,5 segundos. Também testei com o Apache Bench e um alto valor de simultaneidade e pude ver o servidor responder gerando trabalhadores, mas ainda tinha bastante RAM livre:
ab -n 1000 -c 100 "https://example.com/"
Eu verifiquei a RAM com:
free -h
Isso parece estar funcionando por enquanto, embora seja extremamente decepcionante não conseguir fazer o Apache usar o fastCGI usando os instaladores do Ubuntu.