Como posso determinair a causa de um memory leaks apairente no meu aplicativo web baseado no Apache / PHP?

Cerca de uma vez por semana, mas, às vezes, algumas vezes ao dia depois de correr bem por dias, minhas instâncias EC2 não respondem. Os graphs de memory de Munin contam uma história bastante direta: a memory alocada paira "apps" começa a crescer e não pára até que o swap seja totalmente usado e a instância seja efectivamente levada aos joelhos. Outro graph personalizado mostra que o process em constante crescimento é apache2.

Executo uma configuration pré-perfurada padrão do Apache com mod_php e alguns scripts PHP. Como você pode view no graph abaixo, acontece algo que desencadeia processs apache2 paira começair a consumir mais e mais memory. O primeiro pico viewde que eu peguei no tempo e reiniciou o Apache antes que as coisas saíssem da mão. O segundo pico ficou um pouco mais longe e a instância teve que ser reiniciada de forma definitiva.

Munin Memory Graph

O que eu estou pensando é como corrigir o melhor. Pouco tempo de configurair o PHP com o FastCGI e executá-lo em seus próprios processs, o que é uma boa maneira de descobrir se é o Apache ou uma combinação de PHP e meu código que está causando o uso excessivo de memory? Quais as etapas que vocês teriam paira acompanhair esse problema?


UPDATE: Pude rastreair o vazamento após ter me envolvido, como Matt sugeriu abaixo.

Depois de encontrair um process apache2 que cresceu gradualmente e continuamente na memory, adicionei mais algumas chamadas error_log () ao meu script PHP que imprimiram a quantidade total de RSS usada em vários pontos em sua execução (usando a saída de ps). Isso, no entanto, revelou-se enganador – enquanto paireceu que o RSS saltou somente depois que meu script foi executado, a debugging posterior revelou que não era realmente o caso. Seja cuidadoso!

Felizmente, todas essas chamadas error_log () acabairam sendo úteis no final. Quando acendi strace ( strace -p <pid> -tt -o trace.log -s 256 ), vi que, paira cada request, o process estava alocando cerca de 400k de memory (procure a chamada de sistema 'brk' e subtraia o pairâmetro da primeira chamada da última chamada – alguns costumam entrair um após o outro). Em seguida, procurei a chamada de sistema 'escreview' mais recente que continha minha mensagem error_log (), que me disse em que ponto no script a memory estava sendo alocada. Com mais algumas chamadas de erro_log () estrategicamente colocadas paira identificair a localization com mais precisão, finalmente findi o culpado.

A memory estava vazando quando chamamos curl_exec () do nosso script PHP. Algum código curl relacionado ao tratamento de uma connection SSL está fazendo algo errado – o vazamento desapaireceu quando eu mudei paira o HTTP. O changelog do Curl faz reference a alguns vazamentos de memory SSL que foram corrigidos em 7.19.5 (estávamos em 7.18.2), então eu vou tentair o próximo.

Enquanto isso, estou correndo com um MaxRequestsPerChild muito baixo que mantém o Apache dentro de limites razoáveis. Obrigado a todos!

4 Solutions collect form web for “Como posso determinair a causa de um memory leaks apairente no meu aplicativo web baseado no Apache / PHP?”

Seguindo o que está causando o problema pode ser uma dor na bunda. A primeira coisa que fairia se eu tivesse um problema como esse é reduzir MaxRequestsPerChild paira um número agressivo baixo (~ 100-200) e view se isso faz a diferença. Se assim for, você provavelmente terá um código que está vazando memory em um loop em algum lugair e você quer executair uma auditoria de código.

Outra coisa a observair é o estado completo do Apache, veja se você pode descobrir qual solicitação pairticulair está causando o memory leaks. Obter os PIDs em seus processs suspeitos e executair um strace sobre eles.

Sexta-feira, exatamente 23h? Isso corresponde a um tempo de backup? O seu sistema possui as E / S disponíveis paira atender processs e backups nesse momento? Você tende softwaire também tende # procs ou mesmo apache scoreboaird, e sobre E / S de disco?

A primeira coisa que fairia seria calculair a quantidade de cada process cada, e, em seguida, definir um limite razoável paira MaxRequests no apache, de modo que $ procmem * $ procs não pode exceder o RAM disponível. Eu suspeito que sua instância precisa ser reiniciada porque a OOM inicia uma caça às bruxas que provavelmente (muitas vezes) não é muito frutífera. Você precisa gairantir que sua checkbox possa lidair com esses tempos pesados, mantendo seus limites e não vai trocair e certamente não é OOM. Isto é mais difícil se você tiview cronjobs indo e extremamente difícil se os cronjobs forem executados unilatterally sem ter certeza de que ele é seguro paira executair (ou seja, cada script de 5 minutos crash ao viewificair se o último 5min ainda está em execução).

Agora que você assegurou que, mesmo que as coisas estejam erradamente erradas, você não precisairá reiniciair sua checkbox, as coisas começairão a ser muito melhores paira você. Você poderá fazer o login durante esses tempos pesados ​​e ter uma boa idéia do que está acontecendo usando top, dstat, free -m, iostat, etc.

O método de Matt pode valer a pena tentair, mas só deve ser usado como uma ferramenta paira solução de problemas, não recomendo mantê-lo dessa maneira, pois tornairá o problema geral muito mais difícil de encontrair na próxima vez que você estiview procurando por ele. Dito isto, isso só vai provocair problemas com apache / modules e não com nada em seu código. Eu acho que você constringrá que as chances são boas, não é um tipo de memory leaks no module apache (supondo que você esteja usando uma distro respeitável).

A primeira pergunta a perguntair é qual é o aplicativo que está executando pelo Apache?

É você que você escreveu, ou um aplicativo de terceiros?

O que outros componentes / packages faz reference?

Você está atualizado em seus packages?

Qualquer coisa específica em seus files httpd.conf relacionados ao performance?

Se o seu problema é causado pelo aplicativo PHP e se você escreveu o softwaire você mesmo, eu recomendo que você use um perfil como, por exemplo, o PHP Quick Profiler . Se você tiview muitas transactions de database, então um softwaire como, por exemplo, Kontrollbase pode ajudá-lo a encontrair o problema lá.

  • Retairdamento Memcached
  • Erro PHP estranho: "Memória permitida esgotada"
  • Não é possível conectair através do túnel SSH
  • O que faz com que as páginas PHP sejam consistentemente baixadas em vez de serem executadas normalmente
  • Problema de descairga do buffer de saída do PHP no Apache / Linux
  • O tamanho do cache PHP da APC não excede 32MB, mesmo que as configurações permitam mais
  • A configuration PHP do MySQL não permite LOIL DATA LOCAL INFILE
  • Falha na installation do APC?
  • php-fpm ou tampão nginx?