1

毎分実行され、マルチテナント アプリケーションの内部 cron ロジックを実行する cron ジョブがあります。PHP スクリプトは、各クライアントとそのドメインを取得し、それ自体をフォークして、各クライアントの「スコープ」(内部名) の下で実行します。下記参照:

<?php

$i = 0;
foreach($clients as $client) {
    $client->get_domains();
    foreach($client->domains as $domain) {
        $threads[$i]['client'] = $client->id;
        $threads[$i]['domain'] = $domain->id;
        $i++;
    }
}

$pids = array();
foreach($threads as $key => $thread) {
    $pids[$key] = pcntl_fork(); 
    if(!$pids[$key]) {
        $start = microtime(TRUE);
        $handle = popen($args[0] . ' --client ' . $thread['client'] . ' --domain ' . $thread['domain'] . ' 2>&1', 'r');
        // $end1 = ~0.001 sec execution time
        pclose($handle);
        // $end2 = ~60 sec execution time
        exit();
    }
}

現在、負荷を別のサーバーに移行しているため、Ubuntu 11.04 を新規インストールして、既存のマシンのようにセットアップします。アプリでは約 40 個のドメインが実行されているため、1 秒以内に 40 個のフォークが作成されます。

私の問題は、フォークされた各プロセスが単純にプロセスを返すイベントがTRUE約 60 秒かかることです。

時間をダンプする$end1とき、予想どおり、popen() は約 0.001 秒かかります。$end2ただし、 pclose() を監視する場合、約 60 秒かかります。

htop を見ると、プロセスは表示されますが、一時停止しているように見えます。VM には 4 つの CPU と 16GB の RAM があり、実行中のサーバーの負荷は 0.1 未満です。Ubuntu 11.10 で PHP 5.3.6 を実行しています。

OS/PHPの設定上の何かな気がしますがulimitは普通でPHPのメモリ制限や最大実行時間は無制限です。他に確認すべきことはありますか?

4

1 に答える 1

1

ドキュメントに記載されているように、「pclose()関数は、関連するプロセスが終了するのを待ちます。」あなたのデザインは、多くのレベルで実際には意味がありません。スレッドを使用したり、を使用したりする理由は何もないようpopenです。これらの決定を賢明にするコードは他にもありますか?これは本当に「アリを殺すための水爆」プログラムのように見えるからです。fork/を使用するだけexecです。

于 2012-08-13T12:41:45.967 に答える