O que eu faria nessa situação é executar
strace -f -p <PID> -tt -T -s 500 -o trace.txt
em um de seus processos do Apache durante o teste ab até capturar uma das respostas lentas. Então dê uma olhada em trace.txt
.
As opções -tt
e -T
fornecem registros de data e hora do início e da duração de cada chamada do sistema para ajudar a identificar as lentas.
Você pode encontrar uma única chamada de sistema lenta, como open()
ou stat()
, ou pode encontrar uma chamada rápida com (possivelmente vários) poll()
chamadas diretamente após ela. Se você encontrar um que esteja operando em um arquivo ou conexão de rede (muito provavelmente), olhe para trás no rastreio até encontrar esse arquivo ou identificador de conexão. As chamadas anteriores no mesmo identificador devem dar uma ideia do que o poll()
estava esperando.
Boa ideia olhando para a opção -c
. Você se certificou de que o filho do Apache que estava rastreando atendia pelo menos uma das solicitações lentas durante esse período? (Eu nem sei como você faria isso além de executar strace
simultaneamente em todas as crianças.)
Infelizmente, strace
não nos fornece a visão completa do que um programa em execução está fazendo. Apenas rastreia as chamadas do sistema. Muita coisa pode acontecer dentro de um programa que não requer pedir nada ao kernel. Para descobrir se isso está acontecendo, você pode ver os timestamps do início de cada chamada do sistema. Se você ver lacunas significativas, é aí que o tempo está indo. Isso não é facilmente aceitável e sempre há pequenas lacunas entre as chamadas do sistema.
Desde que você disse que o uso da CPU permanece baixo, provavelmente não há coisas excessivas acontecendo entre as chamadas do sistema, mas vale a pena verificar.
Olhando mais de perto a saída de ab
:
O salto repentino nos tempos de resposta (parece que não há tempos de resposta entre 150ms e 3000ms) sugere que há um tempo limite específico acontecendo em algum lugar que é acionado acima de 256 conexões simultâneas. Uma degradação mais suave seria esperada se você estivesse ficando sem memória RAM ou ciclos normais de I / O.
Em segundo lugar, a resposta ab
lenta mostra que os 3000ms foram gastos na fase connect
. Quase todos eles levaram cerca de 30ms, mas 5% levaram 3000ms. Isso sugere que a rede é o problema.
Onde você está executando ab
? Você pode experimentá-lo na mesma rede que a máquina Apache?
Para mais dados, tente executar tcpdump
em ambas as extremidades da conexão (preferencialmente com ntp
em execução nas duas extremidades para que você possa sincronizar as duas capturas) e procure por quaisquer retransmissões tcp. O Wireshark é particularmente bom para analisar os despejos porque destaca as retransmissões de tcp em uma cor diferente, tornando-as fáceis de encontrar.
Também pode valer a pena examinar os registros de todos os dispositivos de rede aos quais você tem acesso. Recentemente, tive um problema com um de nossos firewalls, onde ele podia lidar com a largura de banda em termos de kb / s, mas não conseguia lidar com o número de pacotes por segundo que recebia. Chegou a 140.000 pacotes por segundo. Alguns cálculos rápidos em sua ab
run me levam a acreditar que você estaria vendo cerca de 13.000 pacotes por segundo (ignorando os 5% de pedidos lentos). Talvez este seja o gargalo que você atingiu. O fato de que isso acontece em torno de 256 pode ser puramente uma coincidência.