【问题标题】:How to determine which script is being executed in PHP-FPM process如何确定 PHP-FPM 进程中正在执行哪个脚本
【发布时间】:2023-03-20 13:00:01
【问题描述】:

我正在运行 nginx + php-fpm。有什么办法让我知道每个 PHP 进程在做什么?像 apache 中的扩展 mod_status 之类的东西,我可以看到 PID x 的 apache 进程正在处理 URL y。我不确定 PHP 进程是否知道 URL,但获取脚本路径和名称就足够了。

【问题讨论】:

    标签: fastcgi php


    【解决方案1】:

    经过几个小时的谷歌搜索和浏览 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
    

    【讨论】:

    • 另一个非常有用的选项是 ?html,例如:server.com/php-status?full&html(它将输出格式化为 html 表格,这样可以更容易地同时查看所有正在运行的脚本)
    • 如果我在 nginx 配置中添加任何参数,我该如何访问它?
    • @babakfaghihian 是的,您需要将该 URL(例如 /php-status)传递给 php-fpm。
    • 不幸的是,如果您的 PHP 应用程序使用大多数 MVC 框架所做的 URL 重写(也称为“友好 URL”),那么 request URI 将始终显示为 /index.php。实际的 URL 是在 REQUEST_URI 环境变量中传递的,它不会出现在状态输出中。
    • @Marki555 :伙计,你刚刚救了我的命!我一直在追逐一些脚本,这些脚本占用了我的 php-fpm 容器上的内存,并且对我找到的所有方法都没有运气......直到这个http://server.com/php-status?full那个“?full”参数刚刚带来了光明并向我展示了我正在照顾的错误 URI/脚本。非常感谢!
    【解决方案2】:

    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;
    
    }
    

    【讨论】:

    • 是的,我从 php-fpm 知道这个状态,我已经在 munin 和 zabbix 监控中使用它。但是,它仅提供汇总信息,而不提供每个进程的信息。
    • 不要认为除了创建自定义日志记录解决方案或设置访问日志处理之外您可以做更多事情,但这不会为您提供所需的详细信息,例如处理时间。我确信随着 PHP-FPM 的成熟,它们会扩展状态报告。
    • 最后我发现状态页面支持每个进程的信息(见我的回答)。
    【解决方案3】:

    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_NAMESCRIPT_FILENAME 应该与 php-fpm.conf 文件中的 pm.status_path 相同。最后一个参数 (127.0.0.1:9000) 是与 FCGI 服务器的连接,不是 Web 服务器——它应该是同一个 INI 文件中的 listen 参数。如果是socket,可能需要使用sudo进行连接,这种情况下还要使用-E告诉sudo通过环境变量传递给cgi-fcgi
    【解决方案4】:

    您可以使用 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')
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-05
    • 2021-12-07
    • 2014-12-07
    • 2012-10-12
    • 1970-01-01
    • 2014-11-04
    相关资源
    最近更新 更多