일주일에 한 번, 며칠 동안 정상적으로 실행 한 후 하루에 몇 번이라도 EC2 인스턴스가 응답하지 않게됩니다. Munin의 메모리 그래프는 매우 간단한 이야기를 보여줍니다. "앱"에 할당 된 메모리가 커지기 시작하고 스왑이 완전히 사용되고 인스턴스가 효과적으로 무릎을 꿇을 때까지 멈추지 않습니다. 또 다른 사용자 정의 그래프는 지속적으로 성장하는 프로세스가 아파치 2임을 보여줍니다.
mod_php와 몇 가지 PHP 스크립트를 사용하여 표준 prefork Apache 설정을 실행합니다. 아래 그래프에서 볼 수 있듯이 apache2 프로세스가 더 많은 메모리를 사용하기 시작하는 트리거가 발생합니다. 첫 번째 녹색 스파이크가 제 시간에 걸려 아파치가 시작되기 전에 Apache를 다시 시작했습니다. 두 번째 스파이크가 조금 더 멀어졌으며 인스턴스를 완전히 재부팅해야했습니다.
내가 궁금한 것은 이것을 가장 잘 디버깅하는 방법입니다. FastCGI로 PHP를 설정하고 자체 프로세스에서 실행하는 데 부족한 이유는 Apache인지 또는 PHP와 코드의 조합으로 과도한 메모리 사용을 유발하는지 확인하는 좋은 방법은 무엇입니까? 이 문제를 추적하기 위해 어떤 단계를 수행 하시겠습니까?
업데이트 : Matt이 제안한 것처럼 strace가 관련된 후 누출을 추적 할 수있었습니다.
점차적으로 메모리에서 지속적으로 증가하고있는 apache2 프로세스를 찾은 후 PHP 스크립트에 error_log () 호출을 몇 개 더 추가하여 실행시 다양한 지점에서 사용 된 RSS의 총량을 출력했습니다 (ps의 출력 사용). 그러나 그것은 오도 된 것으로 판명되었습니다. 내 스크립트가 실행 된 후에 만 RSS가 뛰어 오르는 것처럼 보였지만 나중에 디버깅은 실제로 그렇지 않았습니다. 조심해!
다행히도 모든 error_log () 호출은 결국 유용한 것으로 판명되었습니다. strace ( strace -p <pid> -tt -o trace.log -s 256
)를 시작했을 때 , 각 요청에 대해 프로세스가 약 400k의 메모리를 할당하는 것을 보았습니다 ( 'brk'시스템 호출을 찾아 마지막 호출의 첫 번째 호출 매개 변수를 빼십시오. 다른 후). 그런 다음 error_log () 메시지가 포함 된 가장 최근의 '쓰기'시스템 호출을 검색하여 메모리에서 메모리가 할당되는 시점을 알려줍니다. 보다 정확하게 위치를 정확하게 찾기 위해 error_log () 호출을 전략적으로 배치하면서 마침내 범인을 발견했습니다.
PHP 스크립트에서 curl_exec ()를 호출했을 때 메모리가 누출되었습니다. SSL 연결 처리와 관련된 일부 컬 코드가 잘못된 일을하고 있습니다 .HTTP로 전환하면 누수가 사라졌습니다. Curl의 changelog는 7.19.5 (우리는 7.18.2에 있음)에서 수정 된 몇 가지 SSL 메모리 누수를 참조하므로 다음에 시도하겠습니다.
그 동안 Apache를 합리적인 범위 내로 유지하는 MaxRequestsPerChild가 매우 낮습니다. 모두 감사합니다!