Sekitar sekali seminggu, tetapi kadang-kadang bahkan beberapa kali sehari setelah berjalan baik selama berhari-hari, mesin virtual EC2 saya menjadi tidak responsif. Grafik memori Munin menceritakan kisah yang sangat mudah: memori yang dialokasikan untuk "aplikasi" mulai tumbuh dan tidak berhenti sampai swap sepenuhnya digunakan dan instance secara efektif diturunkan hingga ke lutut. Grafik kustom lain menunjukkan bahwa proses yang terus berkembang adalah apache2.
Saya menjalankan setup Apache prefork standar dengan mod_php dan beberapa skrip PHP. Seperti yang dapat Anda lihat pada grafik di bawah ini, terjadi sesuatu yang memicu proses apache2 untuk mulai menggunakan lebih banyak memori. Lonjakan hijau pertama yang saya ingat waktu dan restart Apache sebelum semuanya keluar dari tangan. Lonjakan kedua menjadi sedikit lebih jauh dan instans harus reboot langsung.
Yang saya ingin tahu adalah bagaimana cara terbaik men-debug ini. Kurang menyiapkan PHP dengan FastCGI dan menjalankannya dalam prosesnya sendiri, apa cara yang baik untuk mengetahui apakah itu Apache atau kombinasi PHP dan kode saya yang menyebabkan penggunaan memori yang berlebihan? Langkah apa yang akan kalian lakukan untuk melacak masalah ini?
UPDATE: Saya bisa melacak kebocoran setelah terlibat, seperti yang disarankan Matt di bawah ini.
Setelah menemukan proses apache2 yang secara bertahap dan terus tumbuh dalam memori, saya menambahkan beberapa error_log () panggilan ke skrip PHP saya yang mencetak jumlah total RSS yang digunakan di berbagai titik dalam pelaksanaannya (menggunakan output ps). Namun itu ternyata menyesatkan - sementara tampaknya RSS melonjak hanya setelah skrip saya selesai dieksekusi, kemudian debugging mengungkapkan bahwa bukan itu masalahnya. Hati-hati!
Untungnya, semua panggilan error_log () ini ternyata bermanfaat pada akhirnya. Ketika saya menjalankan strace ( strace -p <pid> -tt -o trace.log -s 256
), saya melihat bahwa untuk setiap permintaan, proses mengalokasikan sekitar 400k memori (mencari panggilan sistem 'brk' dan mengurangi parameter panggilan pertama dari panggilan terakhir - beberapa biasanya datang dalam satu setelah yang lainnya). Saya kemudian mencari panggilan sistem 'tulis' terbaru yang berisi pesan error_log () saya, yang memberi tahu saya pada titik mana dalam skrip memori yang dialokasikan. Dengan beberapa panggilan error_log () yang ditempatkan lebih strategis untuk menentukan lokasi dengan lebih akurat, akhirnya saya menemukan pelakunya.
Memori bocor ketika kami memanggil curl_exec () dari skrip PHP kami. Beberapa kode ikal yang terkait dengan penanganan koneksi SSL melakukan kesalahan - kebocoran hilang ketika saya beralih ke HTTP. Curel's changelog mereferensikan beberapa kebocoran memori SSL yang diperbaiki pada 7.19.5 (kami menggunakan 7.18.2) jadi saya akan mencobanya nanti.
Sementara itu, saya menjalankan dengan MaxRequestsPerChild yang sangat rendah yang menjaga Apache dalam batas yang wajar. Terimakasih semuanya!
sumber
Jawaban:
Melacak APA yang menyebabkan masalah bisa jadi menyebalkan. Hal pertama yang akan saya lakukan jika saya memiliki masalah seperti itu adalah mengurangi
MaxRequestsPerChild
ke angka yang sangat rendah (~ 100-200) dan melihat apakah itu membuat perbedaan. Jika ya, maka Anda mungkin memiliki kode yang membocorkan memori dalam satu lingkaran di suatu tempat dan Anda ingin menjalankan audit kode.Hal lain yang perlu dilihat adalah status penuh Apache, lihat apakah Anda dapat mengetahui permintaan khusus apa yang menyebabkan kebocoran memori. Dapatkan PID pada proses yang Anda duga dan jalankan strace pada mereka.
sumber
Jumat @ tepat 11 malam? Apakah itu sesuai dengan waktu cadangan? Apakah sistem Anda memiliki I / O yang tersedia untuk melayani proses dan cadangan pada waktu itu? Apakah Anda trending software juga tren # procs atau bahkan apache papan skor, bagaimana dengan disk I / O?
Hal pertama yang akan saya lakukan adalah menghitung berapa banyak mem yang diambil setiap proc, kemudian menetapkan batas yang wajar untuk MaxRequests di apache sehingga $ procmem * $ procs tidak dapat melebihi ram yang tersedia. Saya curiga instance Anda perlu di-boot ulang karena OOM memulai perburuan penyihir yang kemungkinan (sering) tidak terlalu membuahkan hasil. Anda perlu memastikan bahwa kotak Anda dapat menangani masa-masa sulit ini dengan tetap berada dalam batasnya dan tidak pergi untuk bertukar dan tentu saja bukan OOM. Ini lebih sulit jika Anda memiliki cronjobs, dan sangat sulit jika kata cronjobs berjalan tanpa bantuan tanpa memastikan itu aman untuk dijalankan (yaitu setiap skrip 5 menit gagal memeriksa apakah 5 menit terakhir masih berjalan).
Sekarang setelah Anda memastikan bahwa meskipun ada kesalahan besar, Anda tidak perlu me-reboot kotak Anda, semuanya akan mulai jauh lebih baik untuk Anda. Anda akan dapat login selama masa-masa sulit ini dan mendapatkan ide bagus tentang apa yang terjadi menggunakan top, dstat, free -m, iostat, dll.
Metode Matt mungkin layak untuk dicoba, tetapi seharusnya hanya digunakan sebagai alat untuk pemecahan masalah, saya tidak menyarankan menjaganya seperti itu karena itu akan membuat masalah keseluruhan jauh lebih sulit untuk menemukan waktu berikutnya Anda mencarinya. Yang mengatakan, itu hanya akan benar-benar mengatasi masalah dengan apache / modul dan bukan apa pun dalam kode Anda. Saya pikir Anda akan setuju kemungkinannya baik itu bukan semacam kebocoran memori dalam modul apache (dengan asumsi Anda menggunakan distro yang memiliki reputasi baik).
sumber
Pertanyaan pertama yang harus ditanyakan adalah apakah aplikasi berjalan melalui Apache?
Apakah itu yang Anda tulis, atau aplikasi pihak ketiga?
Apa komponen / paket lain yang dirujuknya?
Apakah Anda mutakhir tentang paket Anda?
Adakah yang spesifik dalam
httpd.conf
file Anda yang terkait dengan kinerja?sumber
Jika masalah Anda disebabkan oleh aplikasi PHP dan jika Anda menulis sendiri perangkat lunaknya maka saya sarankan Anda untuk menggunakan profiler seperti misalnya PHP Quick Profiler . Jika Anda memiliki banyak transaksi basis data yang sedang berjalan maka sebuah perangkat lunak seperti misalnya Kontrollbase dapat membantu Anda menemukan masalah di sana.
sumber