NGINX+PHP-FPM:是否可以關聯 php-fpm PID 來存取日誌條目?

NGINX+PHP-FPM:是否可以關聯 php-fpm PID 來存取日誌條目?

我們一直在使用 NGINX 和 php-fpm。

我們注意到一些請求掛起很長時間(10+、20+分鐘......)透過頂部命令。
另外,在訪問日誌條目(NGINX)中檢測到了一些可疑請求(我的意思是機器人),但我不確定這些可疑請求是否與那些掛起的請求有任何關係。

所以我的主要問題是:

是否可以(透過設定或其他方式)將 php-fpm PID 關聯到存取日誌中的 URL 條目?
或是有什麼工具可以幫助我完成這項任務?

附加資訊:
我們擁有原始碼,因為我們是主要開發人員。

先致謝!

答案1

從 nginx 端識別正確的 php-fpm 進程是有問題的,因為您本質上是透過 unix 套接字或 tcp 套接字與黑盒進行通信,更不用說線程了。

您可以從 php 方面解決該問題。您可以在 php 腳本中使用 getmypid(),或者如果這不是您的程式碼,您可以在 php fpm 配置中使用 php_value auto_prepend_file 選項。這樣,您可以在每個 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

然後只需在 PHP 中記錄您的 pid:

# 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 的慢日誌:設定request_slowlog_timeout以及slowlog- 請參閱php-fpm 配置文檔- 應該為您提供所有長時間運行的 php-fpm 進程的堆疊追蹤;包括他們的PID。

相關內容