Apache / PHP tabanlı web uygulamamda görünür bir bellek sızıntısının nedenini nasıl belirleyebilirim?


18

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.

Munin Bellek Grafiği

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!


Apache alt süreçlerinin sayısı aynı dönemde nasıl değişir?
SimonJ

@SimonJ Simon, harika bir soru, sayı hemen hemen aynı kaldı, artı eksi birkaç işlem. Sunucular sorun yaşadığında ve istirahat ettiklerinde 60 civarında seyrediyor. Yine de% 100 emin olmak için bir Munin grafiği ayarlayacağım.
ondrej

Çözüm değil, ancak uygulamalardan birinin RAM'i deli gibi yediği biliniyorsa, takasın kapalı kalması daha iyidir: çekirdek RAM eksikliğini tespit ettiğinde, en büyük bellek domuzlarını (apache) öldürür. Takas etkinleştirildiğinde, çekirdek bazı işlemleri çok daha sonra öldürür, çünkü takas RAM'den çok daha yavaştır. Takas yok - daha hızlı iyileşme, daha kısa duruş süresi. (Ben sadece 8GiB RAM, bu nedenle YMMW bir makinede benzer bir durumda takas devre dışı bırakmayı denedim.)
chronos

Yanıtlar:


5

Soruna Neyin yol açtığını izlemek kıçta bir ağrı olabilir. Böyle bir sorunum olsaydı yapacağım ilk şey, MaxRequestsPerChildagresif derecede düşük bir sayıya (~ 100-200) düşürmek ve bunun bir fark yaratıp yaratmadığını görmek. Varsa, muhtemelen bir yerde bir döngüde bellek sızdıran kodunuz vardır ve bir kod denetimi çalıştırmak isteyeceksiniz.

Bakılacak başka bir şey de Apache'nin tam durumu, hangi sızıntının bellek sızıntısına neden olduğunu öğrenip öğrenemeyeceğinize bakın. Şüphelendiğiniz süreçlere ilişkin PID'leri alın ve bunlara baskı uygulayın.


Teşekkürler Matt. 'ps aux | grep apache2 bana aktif olan 60 kadar işlemden yaklaşık bir düzine kadar olması gerekenden çok daha fazla bellek kullandığını söylüyor (RSS'de> 100MB). / Proc / <pid> / smaps çıktısına baktım ve her birinin alanın% 95'ini kaplayan tam olarak anonim bir haritaya sahip olduğunu gördüm. Şimdi bu devasa bellek yığınını ne zaman ve ne zaman tahsis ettiğimi anlamaya çalışıyorum. Strace'a bakacağım - bahşiş için teşekkürler.
ondrej

2

Cuma tam 23:00? Bu bir yedekleme süresine karşılık geliyor mu? Sisteminizde o anda süreç ve yedeklemeler sunmak için G / Ç mevcut mu? Trend olan yazılımlar da # procs veya apache skorbordunu trend ediyor mu, disk G / Ç'sine ne dersiniz?

İlk ben her proc alır ne kadar Mem hesaplamak olacaktır yapacağını şey, daha sonra apache böylece $ ProcMem * $ procs geçemez mevcut ram içinde MaxRequests için makul bir limit tespit etmiştir. Örneğinizin yeniden başlatılması gerektiğinden şüpheleniyorum çünkü OOM muhtemelen (çoğu zaman) çok verimli olmayan bir cadı avını başlattı. Sen lüzum kendi sınırları içinde kalarak bu ağır kez işleyebilir kutuyu sağlamak ve OOM kesinlikle takas gidip değil. Eğer cronjobs devam ederse bu daha zordur ve eğer söz konusu cronjobs çalıştırılmayacağından emin olmadan tek yönlü çalışırsa son derece zordur (yani her 5 dakikada bir komut dosyası son 5 dakikanın hala çalışıp çalışmadığını kontrol edemez).

Artık işler çılgınca gitse bile, kutunuzu yeniden başlatmanıza gerek kalmayacağından, işlerin sizin için çok daha iyi gitmeye başlayacağına emin oldunuz. Bu yoğun zamanlarda giriş yapabilir ve top, dstat, free -m, iostat, vb.'yi kullanarak neler olduğu hakkında iyi bir fikir edinebilirsiniz.

Matt'in yöntemi denemeye değer olabilir, ancak yalnızca sorun giderme için bir araç olarak kullanılmalıdır, bu şekilde tutmanızı önermiyorum, çünkü bir dahaki sefere aradığınızda genel sorunu daha zor hale getirecektir. Bununla birlikte, kodunuzdaki hiçbir şeyi değil, yalnızca apache / modülleri ile ilgili sorunları gerçekten kızdırır. Sanırım şansın iyi olduğunu kabul edersiniz, bu apache modülünde bir çeşit bellek sızıntısı değildir (saygın bir dağıtım kullandığınızı varsayarsak).


0

Sorulması gereken ilk soru, uygulamanın Apache üzerinden ne çalıştırdığıdır.

Yazdığınız bir uygulama mı yoksa üçüncü taraf bir uygulama mı?

Başka hangi bileşenlere / paketlere başvuruyor?

Paketleriniz hakkında güncel misiniz?

httpd.confDosyalarınızda performansla ilgili özel bir şey var mı?


0

Sorununuz PHP uygulamasından kaynaklanıyorsa ve yazılımı kendiniz yazdıysanız, örneğin PHP Quick Profiler gibi bir profiler kullanmanızı öneririz . Çok fazla veritabanı işlemi devam ediyorsa, örneğin Kontrollbase gibi bir yazılım sorunu orada bulmanıza yardımcı olabilir.


Raffael, teşekkürler. Evet, PHP uygulaması benimdir ve herhangi bir SQL veritabanına çarpmaz. PHP Quick Profiler'a bir şans vereceğim ve rapor vereceğim.
ondrej
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.