Приблизно раз на тиждень, але іноді навіть пару разів на день після нормальної роботи днями, мої 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 в розумних межах. Дякую всім!