Мониторинг/профилирование процессов php-fpm

Недавно я столкнулся с проблемой использования процессов php-fpm (как и количества активных процессов), достигая максимума доступных процессов и тем самым прекратив выполнение других скриптов до тех пор, пока не закончились проблемные процессы.

Более подробно, мои текущие настройки php-fpm:

pm = static
pm.max_children = 100

Я смотрю страницу статуса php-fpm, которая показывает большую часть времени:

total processes: 100
idle processes: 95-99
active processes: 1-5

что является нормальным. Тем не менее, каждые несколько минут количество активных процессов перескакивает до 100 в течение нескольких секунд, а затем возвращается к нормали 1-5. в то время все остальные скрипты, запущенные на сервере, просто застревают в течение этого периода времени. (Из браузера вы просто видите, что страница ждет).

Теперь я проверил, не влияет ли его на конкретные трафик трафика, но его нет. он также может иметь место с наименьшим количеством трафика дня.

Я считаю, что определенный script, может быть, даже в особых ситуациях, заставляет php просто использовать все доступные процессы по какой-либо причине.

Эта проблема началась, когда мы перешли на PHP 5.4.X из 5.2.X

В настоящее время у нас есть около 60 веб-сайтов, поэтому его любопытство проходит через каждый веб-сайт и проверяет его.

В nginx-журналах ничего нет (ничто не критично, есть несколько уведомлений и т.д.).

То, что я пытаюсь сделать, - это как-то трассировка/профиль/монитор, которые php-fpm script использует процессы, поэтому я буду знать, с чего начать поиск проблемы.

Возможно ли это? Может быть, другой подход?

Обновление

Вот график процесса процесса PHP-FPM за 1 час, с интервалом в 1 мин:

graph

Я покрасил прыжки, о которых я говорю. Использование памяти во время всплеска остается тем же самым

Ответ 1

В вашем файле журнала php-fpm вы должны увидеть что-то вроде:

 WARNING: [pool www-images] server reached pm.max_children setting (5), consider raising it.

когда количество активных процессов достигает пределов. Вы должны иметь возможность сопоставить это с запросами, которые входят.

Если это не показывает какой-либо шаблон запросов, вызывающих проблему, вы должны добавить медленный журнал в конфигурацию php-fpm:

request_slowlog_timeout = 10
slowlog = /var/log/php-fpm/slow.$pool.log

Запишет трассировку стека для каждого запроса, который занимает больше, чем ограничение slowlog_timeout.

Если это все еще ничего не показывает, либо ваше внутреннее ведение журнала приложений должно показывать, где происходит замедление.

Если этого недостаточно, вы можете использовать strace в качестве последнего средства, которое покажет, какие системные вызовы сделал. Это даст поток информации. Я бы рекомендовал только привязать его к одному процессу strace -p PID, где PID является идентификатором процесса экземпляра php-fpm.

он также может иметь место с наименьшим количеством трафика дня.

Это обязательно должно появиться в медленном протоколе php-fpm. Однако, если это только покажет вам, какой запрос медленный, но не поможет вам понять, почему вы можете добавить отладку с использованием файлов автоматической предварительной и пост-отложенной в конфигурационный файл PHP-FPM.

php_value[auto_prepend_file]=/php_shared/prepend.php
php_value[auto_append_file]=/php_shared/postpend.php

Или просто просто

Вы можете настроить страницу состояния PHP-FPM.

Добавьте это в конфигурацию пула PHP-FPM:

pm.status_path = /www-status

И передайте запросы через nginx в PHP-FPM

location ~ ^/(www-status)$ {
    include       %mysite.root.directory%/conf/fastcgi.conf;
    fastcgi_pass   unix:%phpfpm.socket%/php-fpm-www.sock;

    # or IP address
    # fastcgi_pass 127.0.0.1:9000;

    #If you're fastcgi.conf doesn't set the query_string
    #pass the query string here instead.
    # fastcgi_param  QUERY_STRING  $query_string;


    fastcgi_index index.php;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;

    allow 127.0.0.1;
    allow stats_collector.localdomain;
    allow watchdog.localdomain;
    deny all;
}

Затем переход на сайт yoursite.com/www-status?full даст вам большую распечатку из каждого процесса php-fpm, например:

pool:                 www
process manager:      dynamic
start time:           18/Mar/2013:20:17:21 +1100
start since:          243
accepted conn:        3
listen queue:         0
max listen queue:     0
listen queue len:     0
idle processes:       3
active processes:     1
total processes:      4
max active processes: 1
max children reached: 0
slow requests:        0

************************
pid:                  6233
state:                Idle
start time:           18/Mar/2013:20:17:21 +1100
start since:          243
requests:             1
request duration:     631
request method:       GET
request URI:          /www-status
content length:       0
user:                 -
script:               /documents/projects/intahwebz/intahwebz/basereality/www-status
last request cpu:     0.00
last request memory:  262144

btw Уверен, что это глупый запрос, который блокирует вашу базу данных.