Haftada yaklaşık bir kez, ancak bazen günlerce iyi çalıştıktan sonra günde birkaç kez, EC2 örneklerim yanıt vermiyor. Munin'in bellek grafikleri oldukça basit bir hikaye anlatıyor: "uygulamalara" ayrılan bellek büyümeye başlıyor ve takas tamamen kullanılana ve örnek etkili bir şekilde dizlerine indirilene kadar durmuyor. Bir başka özel grafik sürekli büyüyen sürecin apache2 olduğunu göstermektedir.
Mod_php ve birkaç PHP komut dosyası ile standart bir prefork Apache kurulumu çalıştırıyorum. Aşağıdaki grafikte de görebileceğiniz gibi, daha fazla bellek tüketmeye başlamak için apache2 işlemlerini tetikleyen bir şey oluyor. Zamanla yakaladığım ilk yeşil başak, işler tükenmeden Apache'yi yeniden başlattım. İkinci sivri uç biraz daha uzadı ve örneğin yeniden başlatılması gerekiyordu.
Merak ettiğim şey bunun en iyi nasıl hata ayıklanacağı. PHP'yi FastCGI ile kurmanın ve kendi işlemlerinde çalıştırmanın kısa sürmesi, Apache mi yoksa PHP'nin ve aşırı bellek kullanımına neden olan kodumun bir kombinasyonu olup olmadığını öğrenmenin iyi bir yolu nedir? Bu sorunu izlemek için hangi adımları atacaksınız?
GÜNCELLEME: Matt'in önerdiği gibi, katılıma dahil olduktan sonra sızıntıyı takip edebildim.
Yavaş yavaş ve sürekli olarak bellekte büyüyen bir apache2 işlemi bulduktan sonra, PHP betiğime, yürütme işleminin çeşitli noktalarında (ps çıktısını kullanarak) kullanılan toplam RSS miktarını yazdıran birkaç hata_log () çağrısı ekledim. Ancak bu yanıltıcı olduğu ortaya çıktı - RSS'nin sadece komut dosyam yürütüldükten sonra atladığı görüldü, ancak daha sonra hata ayıklama gerçekten durum böyle değildi. Dikkatli ol!
Neyse ki, tüm bu error_log () çağrıları sonunda yararlı olduğu ortaya çıktı. Ben strace (yukarı kovunca strace -p <pid> -tt -o trace.log -s 256
), ben her istek için, süreç 'brk' sistem çağrısı için yaklaşık 400k belleğe (görünüm içinde tahsis edilmiş ve son çağrı en birinci çağrının parametreyi çıkarma gördüm - Birkaç genellikle birinde gel birbiri ardına). Sonra benim hata_log () mesajını içeren en son 'yazma' sistem çağrısı için aradım, hangi bana komut dosyasında hangi noktada bellek tahsis edildi anlattı. Konumu daha doğru bir şekilde belirlemek için birkaç stratejik olarak yerleştirilmiş error_log () çağrısı ile, nihayet suçluyu buldum.
PHP betiğimizden curl_exec () çağrıldığında bellek sızdırıyordu. SSL bağlantısıyla ilgili bazı kıvrılma kodları yanlış bir şey yapıyor - HTTP'ye geçiş yaptığımda sızıntı gitti. Curl'un changelog'u 7.19.5'te (7.18.2'deydik) düzeltilen birkaç SSL bellek sızıntısına başvuruyor, bu yüzden bir daha deneyeceğim.
Bu arada, Apache'yi makul sınırlar içinde tutan çok düşük bir MaxRequestsPerChild ile çalışıyorum. Herkese teşekkürler!