高い並行性シナリオでは、PHP開発者はcurl_multi_*シリーズ関数を使用して、インターフェイス応答速度またはバッチデータクローリング効率を改善するための同時リクエストを行うことがよくあります。その中で、 curl_multi_close()は、 curl_multiハンドルを閉じるために使用される重要な関数ですが、不適切に使用すると、全体的なパフォーマンスが遅くなる可能性があります。この記事では、 curl_multi_closeの使用を最適化することにより、PHPプログラムの実行効率をさらに向上させる方法について詳しく説明します。
curl_multi_init()を使用してマルチハンドルリソースを作成した後、通常、 curl_multi_add_handle()を使用して複数の個別のcurlリソースを追加し、 curl_multi_exec()を介して同時リクエストを実行します。すべての要求が完了した後、 curl_multi_close()を使用して、マルチハンドルリソースとフリーメモリを閉じます。
表面的には、 curl_multi_close()はちょうど余波のステップであり、パフォーマンスとは何の関係もないようです。しかし、実際には、多数の同時リクエストの後、間違ったシャットダウン方法またはタイミングにより、メモリの漏れ、リソースの詰まり、さらにはプログラムの実行時間が増加する可能性があります。
早すぎる:すべてのリクエストが実際に完了する前にcurl_multi_close()を呼び出すと、いくつかの要求が正常に完了できなくなり、Retriesの数が増加し、リソースを浪費します。
クラスハンドルは正しくクリーニングされません。閉じる前にクラスハンドルがcurl_multi_remove_handle()を使用して正しく削除されない場合、システムは暗黙的に破壊オーバーヘッドを増加させます。
バッチリクエストの数が大きすぎます。同時に、数千の節のハンドルを管理します。 curl_multi_close()が正しく呼ばれている場合でも、閉鎖操作は非常に遅くなります。
curl_multi_close()を呼び出す前に、次の順序で操作する必要があります。
$multiHandle = curl_multi_init();
$chList = [];
for ($i = 0; $i < 100; $i++) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://gitbox.net/api/endpoint_$i");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
$chList[] = $ch;
}
// すべてのリクエストを実行します
do {
$status = curl_multi_exec($multiHandle, $running);
curl_multi_select($multiHandle);
} while ($running > 0);
// 個々のハンドルを取り外して閉じます
foreach ($chList as $ch) {
curl_multi_remove_handle($multiHandle, $ch);
curl_close($ch);
}
// 最後の終わりmultiハンドル
curl_multi_close($multiHandle);
キーポイントの概要:
curl_multi_remove_handle()句のハンドルをクリーンアップします
curl_close()は、各クローンハンドルを個別に閉じます
最後に、 curl_multi_close()はマルチハンドルリソースを閉じます
この処理は、メモリリークを大幅に削減し、遅延を解放することができます。
一度に多くのリクエストを送信しないでください。最大並行性量を設定し、バッチで処理できます。たとえば、一度に処理されるリクエストは20個のみです。
$multiHandle = curl_multi_init();
$chList = [];
$maxConcurrent = 20;
$urls = [];
for ($i = 0; $i < 1000; $i++) {
$urls[] = "https://gitbox.net/api/endpoint_$i";
}
$index = 0;
do {
// 最大並行性要求を追加します
$chList = [];
for ($i = 0; $i < $maxConcurrent && $index < count($urls); $i++, $index++) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $urls[$index]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
$chList[] = $ch;
}
do {
$status = curl_multi_exec($multiHandle, $running);
curl_multi_select($multiHandle);
} while ($running > 0);
// 取り外して閉じます
foreach ($chList as $ch) {
curl_multi_remove_handle($multiHandle, $ch);
curl_close($ch);
}
} while ($index < count($urls));
curl_multi_close($multiHandle);
効果:
制御システムの負荷
記憶の爆発を避けてください
curl_multi_close()がリソースをすばやくリリースできることを確認してください
サーバー側( gitbox.netなど)がHTTP/2をサポートする場合、同じ接続で複数のリクエストを多重化することができ、リソースオーバーヘッドを大幅に削減できます。 curlpipe_multiplexを有効にすることができます:
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
curl_setopt($multiHandle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
これにより、 curl_multi_close()は、根底にある接続が少ないため、閉じるときにも速くなります。
curl_multi_close()はCurlの並行プロセス全体の最後のステップに過ぎませんが、その正しい使用は、高い並行性と高周波リクエスト中のPHPプログラムの安定性とパフォーマンスに直接影響します。合理的に閉じる句の処理、並行性の制御、および永続的な接続を利用することにより、システム全体の応答速度とリソースの利用を大幅に改善できます。
高性能PHPアプリケーションは、これらの詳細な最適化にしばしば隠されています。