我們一直在使用 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。