Як я можу визначити причину явного витоку пам’яті у веб-додатку на базі Apache / PHP?


18

Приблизно раз на тиждень, але іноді навіть пару разів на день після нормальної роботи днями, мої EC2 випадки не реагують. Графіки пам’яті Муніна розповідають досить просту історію: пам’ять, виділена для «додатків», починає зростати і не припиняється до повного використання свопу та екземпляра ефективно зведеного на коліна. Ще один нестандартний графік показує, що процес, що постійно зростає, є apache2.

Я запускаю стандартну настройку Apache для префорка з mod_php та кількома сценаріями PHP. Як ви бачите на графіку нижче, трапляється щось, що запускає процеси apache2, щоб почати витрачати більше і більше пам'яті. Перший зелений колосок я вчасно зловив і перезапустив Apache, перш ніж речі вийшли з рук. Другий шип став трохи далі і екземпляр довелося перезавантажити прямо.

Графік пам'яті Муніна

Мені цікаво, як найкраще налагодити це. Окрім налаштування PHP за допомогою FastCGI та його запуску у своїх власних процесах, який хороший спосіб з’ясувати, чи це Apache чи комбінація PHP та мого коду, що викликає надмірне використання пам'яті? Які кроки ви б зробили, щоб відстежити цю проблему?


ОНОВЛЕННЯ: Я зміг відстежити витік після залучення напруги, як Метт запропонував нижче.

Знайшовши процес apache2, який поступово і постійно зростав у пам’яті, я додав ще кілька викликів error_log () до свого PHP-скрипту, який роздрукував загальну кількість RSS, що використовується в різних точках його виконання (використовуючи вихід PS). Однак це виявилося оманливим - хоча з'ясувалося, що RSS стрибає лише після виконання мого сценарію, пізніше налагодження виявило, що насправді це не так. Будь обережний!

На щастя, усі ці виклики error_log () виявилися зрештою корисними. Коли я запустив strace ( strace -p <pid> -tt -o trace.log -s 256), я побачив, що для кожного запиту процес виділяє близько 400 кб пам’яті (шукайте системний виклик 'brk' і віднімайте параметр першого виклику від останнього виклику - декілька зазвичай приходять в один після іншого). Потім я шукав останній системний виклик "запис", який містив моє повідомлення error_log (), яке повідомило мені, в який момент у сценарії виділяється пам'ять. З кількома стратегічно розміщеними викликами error_log (), щоб точніше визначити місце, я нарешті знайшов винуватця.

Пам'ять просочувалася, коли ми викликали curl_exec () з нашого PHP-сценарію. Деякий код завитка, пов’язаний з обробкою з’єднання SSL, робить щось не так - витік зник, коли я перейшов на HTTP. Curlog's changelog посилається на кілька витоків пам'яті SSL, які були виправлені в 7.19.5 (ми були на 7.18.2), тому я спробую це наступне.

Тим часом я працюю з дуже низьким MaxRequestsPerChild, що підтримує Apache в розумних межах. Дякую всім!


Як змінюється кількість дочірніх процесів апаш за той самий період?
SimonJ

@SimonJ Simon, велике питання, кількість залишається майже однаковою, плюс мінус кілька процесів. Він наближається до 60, коли сервери відчувають проблеми, а також коли вони знаходяться в спокої. Я встановив графік Муніна, щоб бути впевненим на 100%.
ондрей

Це не рішення, але якщо в одному із застосунків відомо, що він їсть оперативну пам’ять як божевільний, тоді краще не робити своп: коли ядро ​​виявить відсутність оперативної пам’яті, воно вб’є найбільші хоги пам’яті (apache). Якщо увімкнено swap, ядро ​​вбиває деякі процеси набагато пізніше, тому що swap набагато повільніше, ніж оперативна пам'ять. Нічого заміни - швидше відновлення, менший час простою. (Я лише спробував відключити swap у подібному випадку на машині з 8GiB оперативної пам’яті, тому YMMW.)
chronos

Відповіді:


5

Відстеження того, що викликає проблему, може бути болем у попі. Перше, що я зробив би, якби у мене виникла така проблема, як зменшити MaxRequestsPerChildдо агресивно низького числа (~ 100-200) і подивитися, чи це має значення. Якщо це так, то, ймовірно, у вас є код, який десь просочується пам'яттю, і ви захочете запустити аудит коду.

Інша річ, на яку слід звернути увагу - це fullstatus Apache, щоб дізнатися, чи зможете ви дізнатися, який саме запит спричиняє витік пам'яті. Отримайте ПІД на своїх підозрілих процесах та запустіть на них напругу.


Дякую Метт. 'ps aux | grep apache2 'говорить мені, що з 60 або більше процесів, які активно діють, близько десятка використовують набагато більше пам’яті, ніж слід (> 100 Мб в RSS). Я переглянув вихід / proc / <pid> / smaps і виявив, що кожен має точно одне анонімне відображення, яке займає 95% + місця. Зараз я намагаюся розібратися, що і коли виділило цей величезний шматок пам’яті. Я роздивлюся стрази - дякую за пораду.
ондрей

2

П’ятниця @ рівно об 11 годині вечора? Чи відповідає це час резервного копіювання? Чи є у вашій системі доступний I / O для обслуговування процесів і резервного копіювання на той час? Чи є в трендовому програмному забезпеченні також тренди # procs або навіть apache табло, як щодо дискового вводу / виводу?

Перше , що я хотів би зробити було б підрахувати , скільки мем кожен користь приймає, а потім встановити розумну межу для MaxRequests в апача , так що $ procmem * $ пуття не може перевищувати доступної пам'яті. Я підозрюю, що ваш екземпляр повинен бути перезавантажений, оскільки OOM починає полювання на відьом, що, ймовірно, (часто) не дуже плідно. Вам потрібно переконатися, що ваш ящик може справлятися з цими важкими часами, залишаючись в його межах, і не ходити на своп і, звичайно, не OOM. Це складніше, якщо у вас є зайняття кронштейнами, і надзвичайно складно, якщо зазначені кронштейни виконуються в односторонньому порядку, не переконуючись, що це безпечно запустити (тобто кожні 5 хвилин сценарій не може перевірити, чи останній 5 хв все ще працює).

Тепер, коли ви переконалися, що навіть якщо все піде не так, вам не потрібно буде перезавантажувати коробку, все для вас почне набагато краще. Ви зможете увійти в цей важкий час і добре зрозуміти, що відбувається за допомогою top, dstat, free -m, iostat тощо.

Метод Метта, можливо, варто спробувати, але його слід використовувати лише як інструмент для усунення несправностей, я не рекомендую його зберігати таким чином, оскільки це зробить загальну проблему набагато складніше в наступний раз, коли ви її шукаєте. Однак, це буде справді дражнити проблеми з apache / модулями, а не що-небудь у вашому коді. Думаю, ти погодишся, що шанси хороші, що це не якесь протікання пам'яті в модулі apache (якщо припустимо, що ти використовуєш поважний дистрибутив).


0

Перше запитання - це те, що програма працює через Apache?

Це один ви написали, або стороннє додаток?

На які ще компоненти / пакети він посилається?

Ви в курсі своїх пакетів?

Щось конкретне у ваших httpd.confфайлах, пов’язане з продуктивністю?


0

Якщо ваша проблема викликана програмою PHP, і якщо ви написали програмне забезпечення самостійно, я рекомендую вам скористатися профілером, наприклад, PHP Quick Profiler . Якщо у вас відбувається багато транзакцій з базами даних, тоді програмне забезпечення, наприклад, Kontrollbase, може допомогти вам знайти там проблему.


Раффаел, дякую. Так, додаток PHP мій, і він не вражає жодних баз даних SQL. Я дам PHP Quick Profiler зняти та звітувати.
ондрей
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.