【问题标题】:php xdebug: How to profile forked processphp xdebug:如何分析分叉进程
【发布时间】:2013-05-23 03:41:04
【问题描述】:

我正在运行要分析的 PHP 守护程序。

启动的 php 进程加载所有需要的数据,forks 自己将工作负载分配到所有内核上,waits 用于分叉子代完成,并收集子代生成的结果。

由于我与其他用户共享 CLI 环境,我需要通过将 php.ini 值注入 shell 调用来启动 xdebug profiling

 $ php -d xdebug.profiler_enable=1 -d xdebug.profiler_output_dir="/home/xxx" daemon.php

然而,生成的 cachegrind 文件会分析父级,因此显示 90% 的睡眠。

有没有一种方法可以在不构建驱动程序来直接加载工人的情况下对工人进行概要分析?

谢谢

【问题讨论】:

    标签: php fork xdebug profiler


    【解决方案1】:

    我遇到了同样的问题并在没有 XDebug 的情况下解决了。不幸的是,我找不到 XDebug 的方法。就好像它不关心任何分叉的进程。

    我通过使用 Xhprof 分析和 Xhgui 检查日志来解决。 Xhprof 是一个很棒的工具,由 Facebook 内部开发,然后开源发布。 很酷的是,您可以准确地决定何时开始分析以及何时停止。这使您能够解决我们的问题。

    首先让我们安装它!

    sudo pecl install xhprof-beta
    

    如果您使用的是基于 debian 的发行版,请确保您也安装了 graphviz。

    sudo apt-get install graphviz
    

    现在让我们看一下代码。

    $children = [];
    
    do {
        if (count($children) < $maxConsumers) {
            $pid = pcntl_fork();
            $children[] = $pid;
    
            if ($pid == -1) {
                throw new \RuntimeException('Could not fork process');
            } else if ($pid === 0) {
                // we are the child
    
                if ($verbose) {
                    $output->writeln(sprintf('Child here (PID = %s)', posix_getpid()));
                }
    
                if ($xhProf) {
                    // here we enable xhprof thus the profiling starts
                    xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
                }
    
                // DO YOUR MAGIC HERE!
    
                if ($xhProf) {
                    // and here we call the xhgui header file that will
                    // stop xhprof and write all the gathered data into
                    // mongo or into a dedicated file
                    require_once('/var/www/xhgui/external/header.php');
                }
    
                exit;
            } else {
                // we are the parent
                if ($verbose) {
                    $output->writeln(sprintf('Parent here (PID = %s) spawned a new child (PID = %s)', posix_getpid(), $pid));
                }
            }
        } else {
            if ($verbose) {
                $output->writeln(sprintf("Parent - spawned enough children, let's wait them..."));
            }
    
            $deadPID = pcntl_wait($status);
            $children = array_diff($children, [$deadPID]);
    } while (true);
    
    // Waits for all remaining children
    while (($pid = pcntl_waitpid(0, $status)) != -1) {
        if ($verbose) {
            $status = pcntl_wexitstatus($status);
            $output->writeln(sprintf("Child (PID %d) terminated. Status is %s.", $pid, $status));
        }
    }
    

    为了检查您的日志,您还需要正确配置 Xhgui。您可能还需要一个虚拟主机。

    所有需要的配置和参考:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-19
      • 2012-04-19
      • 2011-01-24
      • 1970-01-01
      • 2012-05-05
      • 2013-03-06
      • 2018-09-20
      • 2013-05-26
      相关资源
      最近更新 更多