PHP + Apache longo tempo de espera

4

Eu encontrei uma parede de tijolos com a solução de problemas dos meus webseveres dedicados. Recentemente, meu site aumentou a quantidade de solicitações / por segundo e caiu.

A caixa original tinha 8 GB de RAM, 8 Core Xeon E3-1230, 1 TB 7.200 RPM Disk (No Raid), rede dedicada de 100 Mbits.

Após o aumento, a RAM aumentou para 24 GB para suportar mais usuários simultâneos.

O Apache parece funcionar bem, mesmo com 3000 usuários simultâneos, ele retornará HTML e conteúdo estático muito rapidamente (não armazenado em cache).

Para testar ainda mais as diferenças entre o Apache / HTML e o Apache / PHP, executei ab .

Tanto o test.html quanto o test.php têm exatamente o mesmo conteúdo estático, o PHP não chama include s e não se conecta ao MySQL.

Teste de HTML

ab -n 500 -c 50 http://www.~~.com/test.html

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      252  375 190.3    276    1399
Processing:   254  354 121.5    282     657
Waiting:      253  353 121.4    280     653
Total:        510  730 231.7    573    1675

Teste do PHP

ab -n 500 -c 50 http://www.~~~.com/test.php

Connect:      248  275  51.1    267    1316
Processing:   256 4167 6210.2   2262   41489
Waiting:      253 4166 6210.2   2262   41489
Total:        509 4442 6212.4   2523   41754

Pingdom também reporta um longo tempo de espera ao acessar um script PHP.

EstouobtendoumresultadosemelhantenoWebPageTest.org,emboramelhor,naprimeiravezemqueobyteéF:

LoadTime**FirstByte**StartRenderDOMElementsTimeRequestsBytesInTimeRequestsBytesInFirstView2.061s**0.839s**0.000s552.061s20428KB2.061s20430KB

Aquiestãoosmeusresultadostop:

Teste de E / S

Sob carga pesada, o% wa pode aumentar para 95% por alguns milissegundos.

Eu corri o iostat durante o carregamento:

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           8.37    0.00    5.18    0.56    0.00   85.88

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb               0.00    45.50  3.00 48.00   136.00   748.00    17.33     3.05   59.76   2.53  12.90
sdb1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb2              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb3              0.00    45.50  3.00 48.00   136.00   748.00    17.33     3.05   59.76   2.53  12.90

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           4.00    0.00    3.56    0.69    0.00   91.75

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb               6.00   118.50  9.50 21.00   996.00  1116.00    69.25     0.29    9.44   1.66   5.05
sdb1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb2              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb3              6.00   118.50  9.50 21.00   996.00  1116.00    69.25     0.29    9.44   1.66   5.05

Para mim, isso não parece ruim, mas posso estar perdendo alguma coisa.

Estou usando FCGI

<IfModule mod_fcgid.c>
FcgidMaxRequestLen 1547483648
FcgidMaxRequestInMem 52485760
FcgidIdleScanInterval 15000
FcgidBusyTimeout 15000
FcgidProcessLifeTime 7200
FcgidConnectTimeout 1800
FcgidIOTimeout 1800
PHP_Fix_Pathinfo_Enable 1
FcgidMaxRequestsPerProcess 1000
</IfModule>

E aqui está o meu Apache Conf (estou usando o 2.4.x)

Timeout 60
TraceEnable Off
ServerSignature Off
ServerTokens ProductOnly
FileETag None
StartServers 10
<IfModule prefork.c>
MinSpareServers 5
MaxSpareServers 15
</IfModule>
<IfModule itk.c>
MinSpareServers 5
MaxSpareServers 15
</IfModule>
ServerLimit 2200
MaxRequestWorkers 2000
MaxConnectionsPerChild 15000
KeepAlive On
KeepAliveTimeout 1
MaxKeepAliveRequests 2000

Eu examinei meus logs de erro do Apache e os logs de acesso. Nada de estranho para relatar.

Eu estou realmente coçando minha cabeça aqui.

Eu tentei desativar o firewall.

Eu tentei aumentar o Max Connections.

Otimizei o mySQL e removi muitas consultas lentas (que eram > 0,5s).

O que mais posso fazer? Há algo que eu possa usar para ajudar a identificar problemas? Qualquer ajuda seria muito apreciada.

P.S:

Vale a pena notar que, mesmo quando o servidor está sendo strongmente acessado, o PHPMyAdmin e o cPanel ainda são muito responsivos. Nada mais parece ficar para trás, exceto o PHP no site.

    
por Moe 04.01.2014 / 04:58

2 respostas

1

Eu acho que o seu problema é simplesmente o seu disco rígido com seus tempos de acesso. O Apache pode armazenar em cache páginas html na memória, mas os scripts php não são armazenados em cache; a necessidade de ser executada toda vez novamente. Portanto, o interpretador php é chamado e lê o script do disco rígido. Isso leva muito tempo. A coisa mais lenta no seu servidor é o seu disco rígido. No meu pc, há uma diferença extrema entre os aplicativos que começam no meu SSD e no meu HDD (o SSD é até 10 vezes mais rápido!). Se o seu HDD funcionar, então a latência para executar um script PHP pode aumentar drasticamente.

Possíveis soluções: obtenha um SSD (talvez um pequeno apenas para dados acessados com frequência, como scripts) e minimize as chamadas de script (e acessos a HDD) em seu servidor. Certifique-se de que o sistema de arquivos é desfragmentado (geralmente feito automaticamente). Se o seu script php cria frequentemente o mesmo conteúdo, tente armazená-los em um arquivo html.

Esta resposta também pode ajudá-lo: link

    
por 04.01.2014 / 15:56
2

O arquivo HTML que você está testando é apenas um arquivo simples, tudo o que o Apache precisa fazer é fazer algumas chamadas do sistema (abrir, ler) e depois exibir seu conteúdo.

PHP OTOH é realmente uma opção "pesada": é um interpretador inteiro (bytecode compiler?). E já que você está usando testes simultâneos (-c), quem sabe o quão bem os pedidos são multiplexados para isso? Isso não precisa ser um problema do apache, mas sim o problema do PHP.

O que eu faria:

  1. Alterne para o Apache MPM (multiencadeado em vários processos).

  2. Teste sequencial (sem várias solicitações simultâneas), compare.

  3. Execute valgrind ou algo assim no processo do apache e veja onde a maioria do tempo de CPU é gasto (apache ou PHP).

  4. execute o mesmo teste, mas veicule essa página por meio do nginx. Como o nginx é baseado no modelo assíncrono e muito rápido, se você obtiver resultados semelhantes, o PHP é o culpado.

  5. Finalmente, você pode instalar o Zend Optimizer (o teste de 30 dias é grátis) ou o smth assim: link .

Realmente, comparar a exibição de um arquivo estático em uma página da web gerada dinamicamente é uma comparação entre maçãs e laranjas. Nenhuma das soluções típicas (Python mod-apache, Django, PHP, etc) vai ser muito rápido a este respeito, pelo menos quando comparado a servir um arquivo estático. O Node.js é uma exceção, talvez, devido ao tipo de página da Web de programação "de baixo nível" diretamente no modelo assíncrono.

P.S. você não citou php.ini content. Poste e / ou afine-o.

    
por 04.01.2014 / 15:42