nginx + PHP + MySQL サーバーがあります。MySQL にはジョブを含む大きなデータベースがあります。私が実行している PHP スクリプトは、データベースからすべてのジョブを取得し、すべてのジョブを含む XML フィードを出力する必要があります。スクリプトは現在、このように編成されています
$arr = get_all_job_ids(); //returns 18k PHP array that is fueled by SELECT `id` FROM `jobs`;
foreach ($arr as $i=>$id){
if ($i>9700){break;} //for debugging
$job = get_job_by_id($id); //PHP array generated by SELECT `title`, desc, ... FROM `jobs` WHERE `id`=$id;
$job_xml = replace_job_tags($job, $xml_template); //regular expressions
echo $job_xml;
flush();
}
サーバーには誰もいません。実験専用であり、他には何も実行されていません。まず第一に、SQL の結果を解放し、PHP がクリーンアップしない可能性のあるものを明示的にクリーンアップするようなことを行っても、ループ内で全体的なメモリ消費量が常に増加します。flush() の後に低下しますが、反復開始時のレベルには戻りません。
2 番目に重要なのは、実行時間と CPU 負荷が完全に一致していないことです。場合によっては、9.7k のジョブ フィードが 17 秒以内にうまく生成されることもあります。これらの場合、「top」および「SHOW FULL PROCESSLIST;」に従って。CPU は、get_all_job_ids() ステップ中に一時的に 100% に急上昇しますが、その後落ち着いて、時間をかけてジョブを 1 つずつ取得し、flush() します。
しかし、それ以外の場合、php5-fpm と mysqld は、最初の ID 取得ステップと個々のジョブのループ クエリの両方で、すべての CPU を占有します。また、「SHOW FULL PROCESSLIST;」によるとはいえ、個々のジョブがクエリされている場合、http クライアントは出力を取得せず、代わりに最終的に「504 ゲートウェイ タイムアウト」を受け取ります。比較的長い時間 (分) 後、mysqld と php5-fpm は正常に戻ります。また、 get_job_by_id() ステップを除外し、代わりに配列をハードコーディングすると、すべてがうまくスムーズに実行されます。
私は、これを引き起こしている可能性のあるものと、この問題をさらに明らかにするために他に何ができるかについての考えが完全にありません. 何かアイデアがあれば、喜んでお聞かせください。