12

プロファイリングする PHP デーモンを実行しています。

開始された php プロセスは、必要なすべてのデータをロードし、それ自体をフォークしてすべてのコアにワークロードを分散し、フォークされた子プロセスが終了するのを待ち、子プロセスによって生成された結果を収集します。

CLI 環境を他のユーザーと共有しているため、シェル呼び出しに php.ini 値を挿入してxdebug プロファイリングを開始する必要があります。

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

ただし、生成された cachegrind ファイルは親をプロファイルするため、90% のスリープを示します。

ワーカーを直接ロードするためのドライバーを構築せずにワーカーをプロファイリングする方法はありますか?

ありがとう

4

1 に答える 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 を適切に構成する必要もあります。おそらく仮想ホストも必要になるでしょう。

必要なすべての構成と参照用:

于 2015-07-13T16:44:45.647 に答える