NGINX+PHP-FPM: Возможно ли связать PID php-fpm с доступом к записи журнала?

NGINX+PHP-FPM: Возможно ли связать PID php-fpm с доступом к записи журнала?

Мы используем NGINX и php-fpm.

Мы заметили, что некоторые запросы зависают на долгое время (10+, 20+ минут...) черезвершинакоманда.
Также в записи журнала доступа (NGINX) были обнаружены некоторые подозрительные запросы (я имею в виду ботов), но я не уверен, имеют ли эти подозрительные запросы какое-либо отношение к тем запросам, которые зависли, или нет.

Итак, мой главный вопрос:

Можно ли (через конфигурацию или как-то еще) связать php-fpm PID с записью URL в журнале доступа?
Или есть какой-нибудь инструмент, который мог бы помочь мне с этой задачей?

Дополнительная информация:
У нас есть исходный код, поскольку мы являемся основными разработчиками.

Заранее спасибо!

решение1

Со стороны nginx проблематично определить правильный процесс php-fpm, поскольку по сути вы взаимодействуете с черным ящиком через сокет unix или сокет tcp, не говоря уже о потоках.

Вы можете атаковать проблему со стороны php. Вы можете использовать getmypid() из вашего php-скрипта, или, если это не ваш код, вы можете использовать опцию php_value auto_prepend_file в конфигурации php fpm. Таким образом, вы можете вставить свой собственный код в начало каждого php-файла и регистрировать pid вместе с соответствующим REQUEST_URI по своему усмотрению. У вас есть желаемое соединение. Однако будьте готовы к большим iops на загруженном сайте...

Если вам нужен только pid, может быть проще включить php-status, как описано здесьhttps://easyengine.io/tutorials/php/fpm-status-page/и проверьте yourserver/php-status?full

решение2

Обычно такие проблемы решаются с помощью так называемой RequestId простой установки двух заголовков: X-REQUEST-IDи X-CORRELATION-IDи добавления их в логи как на стороне nginx, так и на стороне php.

RequestIdдолжен быть установлен на случайное значение (я использую UUID) в начале каждого запроса и CorrelationIdдолжен быть установлен на случайное значение при каждом взаимодействии пользователя. Для небольших веб-сайтов обычно есть только один RequestIDи один CorrelationId. Если вы используете микросервисы, то каждый микросервис будет генерировать свой собственный RequestId, но CorrelationIdбудет общим для них.

Реализация зависит от вашей инфраструктуры, но простая реализация может выглядеть так:

# in nginx config
   location / {
      proxy_pass       http://upstream;
      proxy_set_header X-Request-Id $request_id; 
      ...
   }
# or
  location / {
    fastcgi_pass   unix:/path/to/socket;
    fastcgi_param  HTTP_X_REQUEST_ID $request_id;
    ...
  }

# This works because nginx generates a random string and stores it as $request_id

Затем просто зарегистрируйте свой pid в PHP:

# in php-fpm config
# %p - pid
access.format = "[%p][%{HTTP_X_REQUEST_ID}e] %R - %u %t \"%m %r\" %s"
# or in php application itself
# index.php
<?php
file_put_contents('somewhere.log', sprintf('[%s][%d]', $_SERVER['HTTP_X_REQUEST_ID'] ?? 'N/A', getmypid()), FILE_APPEND);
...

решение3

Если у вас включена страница статуса php-fpm, вы можете рассмотреть возможность проверки полного режима для отслеживания pid. Например, используяhttp://example.com/phpfpm-status?fullДолжна быть возможность выяснить, что происходит. (Примечание по безопасности: никогда не следует оставлять такие страницы статуса в открытом доступе.)

решение4

Вам следует использовать функцию PHP-FPM Slow-Log: Настройка, request_slowlog_timeoutа также slowlog— см.Документация по конфигурации php-fpm- должен предоставить вам трассировку стека всех длительно работающих процессов php-fpm, включая их PID.

Связанный контент