【发布时间】:2023-03-20 13:00:01
【问题描述】:
我正在运行 nginx + php-fpm。有什么办法让我知道每个 PHP 进程在做什么?像 apache 中的扩展 mod_status 之类的东西,我可以看到 PID x 的 apache 进程正在处理 URL y。我不确定 PHP 进程是否知道 URL,但获取脚本路径和名称就足够了。
【问题讨论】:
我正在运行 nginx + php-fpm。有什么办法让我知道每个 PHP 进程在做什么?像 apache 中的扩展 mod_status 之类的东西,我可以看到 PID x 的 apache 进程正在处理 URL y。我不确定 PHP 进程是否知道 URL,但获取脚本路径和名称就足够了。
【问题讨论】:
经过几个小时的谷歌搜索和浏览 PHP.net 错误跟踪系统后,我找到了解决方案。它从 PHP 5.3.8 或 5.3.9 开始可用,但似乎没有记录。根据功能请求#54577,状态页面支持选项full,它将分别显示每个工人的状态。因此,例如 URL 将是 http://server.com/php-status?full,示例输出如下所示:
pid: 22816
state: Idle
start time: 22/Feb/2013:15:03:42 +0100
start since: 10933
requests: 28352
request duration: 1392
request method: GET
request URI: /ad.php?zID=597
content length: 0
user: -
script: /home/web/server.com/ad/ad.php
last request cpu: 718.39
last request memory: 1310720
【讨论】:
/php-status)传递给 php-fpm。
request URI 将始终显示为 /index.php。实际的 URL 是在 REQUEST_URI 环境变量中传递的,它不会出现在状态输出中。
http://server.com/php-status?full那个“?full”参数刚刚带来了光明并向我展示了我正在照顾的错误 URI/脚本。非常感谢!
PHP-FPM 有一个内置的状态监视器,虽然它不像 mod_status 那样详细。来自 php-fpm 配置文件 /etc/php-fpm.d/www.conf(在 CentOS 6 上)
; The URI to view the FPM status page. If this value is not set, no URI will be
; recognized as a status page. By default, the status page shows the following
; information:
; accepted conn - the number of request accepted by the pool;
; pool - the name of the pool;
; process manager - static or dynamic;
; idle processes - the number of idle processes;
; active processes - the number of active processes;
; total processes - the number of idle + active processes.
; The values of 'idle processes', 'active processes' and 'total processes' are
; updated each second. The value of 'accepted conn' is updated in real time.
; Example output:
; accepted conn: 12073
; pool: www
; process manager: static
; idle processes: 35
; active processes: 65
; total processes: 100
; By default the status page output is formatted as text/plain. Passing either
; 'html' or 'json' as a query string will return the corresponding output
; syntax. Example:
; http://www.foo.bar/status
; http://www.foo.bar/status?json
; http://www.foo.bar/status?html
; Note: The value must start with a leading slash (/). The value can be
; anything, but it may not be a good idea to use the .php extension or it
; may conflict with a real PHP file.
; Default Value: not set
;pm.status_path = /status
如果启用此功能,则可以将路径从 nginx 传递到 PHP-FPM 的套接字/端口,并且可以查看状态页面。
nginx.conf:
location /status {
include fastcgi_params;
fastcgi_pass unix:/var/lib/php/php-fpm.sock;
}
【讨论】:
cgi命令行更方便:
SCRIPT_NAME=/status \
SCRIPT_FILENAME=/status \
REQUEST_METHOD=GET \
cgi-fcgi -bind -connect 127.0.0.1:9000
【讨论】:
QUERY_STRING=full 才能返回 OP 正在寻找的内容。将SCRIPT_FILENAME 更改为/status?full 不起作用。
pm.status_path 来启用状态页面;这种方法的优点是它不需要被 Web 服务器公开。 SCRIPT_NAME 和 SCRIPT_FILENAME 应该与 php-fpm.conf 文件中的 pm.status_path 相同。最后一个参数 (127.0.0.1:9000) 是与 FCGI 服务器的连接,不是 Web 服务器——它应该是同一个 INI 文件中的 listen 参数。如果是socket,可能需要使用sudo进行连接,这种情况下还要使用-E告诉sudo通过环境变量传递给cgi-fcgi。
您可以使用 strace 实时显示正在运行的脚本以及许多其他内容。它非常冗长,但它可以让您对正在发生的事情有一个很好的整体了解:
# switch php-fpm7.0 for process you're using
sudo strace -f $(pidof php-fpm7.0 | sed 's/\([0-9]*\)/\-p \1/g')
以上将附加到 php fpm 的分叉进程。使用-p 附加到特定的pid。
上面会得到脚本路径。要获取 url,您将查看您的 nginx / apache 访问日志。
附带说明,查看系统调用以及哪些系统调用耗时最长:
sudo strace -c -f $(pidof php-fpm7.0 | sed 's/\([0-9]*\)/\-p \1/g')
稍等片刻,然后按 Ctr-C
【讨论】:
strace -f $(pidof php-fpm | sed 's/\([0-9]*\)/\-p \1/g')