php xdebug:如何对分叉进程进行性能分析

12
我正在运行一个用于分析的PHP守护进程。
启动的PHP进程加载所有所需的数据,将自身分叉以将工作负载分布到所有核心上,等待分叉的子进程完成,并收集子进程生成的结果。
由于我与其他用户共享CLI环境,所以我需要通过将php.ini值注入到shell调用中来启动xdebug分析
 $ php -d xdebug.profiler_enable=1 -d xdebug.profiler_output_dir="/home/xxx" daemon.php

生成的cachegrind文件,然而,对父进程进行了分析,因此显示了90%的睡眠时间。
有没有一种方法可以在不直接构建驱动程序来加载工作进程的情况下对它们进行分析?
谢谢。
1个回答

8
我遇到了相同的问题,并在不使用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。您可能还需要一个虚拟主机。
有关所有所需的配置和参考信息:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接