PHPネットワークリクエストでは、Curlは最も一般的に使用されるツールの1つです。特に、高い同時HTTP要求を処理する場合、カール関連の関数の合理的な使用は、システムの安定性とリソース利用に直接関連しています。この記事では、 curl_close()関数に焦点を当て、高い並行性シナリオでの正しい使用と、誤った使用によって引き起こされる可能性のあるリソース廃棄物の問題について説明します。
Curlは、PHPが提供する強力なネットワークリクエストライブラリであり、HTTP/HTTPSリクエストの開始に使用できます。使用プロセスはおおよそ次のとおりです。
初期化: curl_init()
パラメーターの設定: curl_setopt()
実行リクエスト: curl_exec()
リソースを閉じる: curl_close()
通常、開発者は、各リクエストの後にリソースをリリースする後にcurl_close()を呼び出します。この習慣は、低電流や短期間のスクリプトでは大したことではありませんが、電流が高くなっているか、長期にわたって長期にわたるサービスでは、パフォーマンストラップが隠される可能性があります。
PHPがCurlを使用し、 Curl_shareやcurlopt_forbid_reuseなどのパラメーターを有効にすると、基礎となるLibcurlライブラリは既存の接続(つまり、接続プール)の再利用を試みます。接続の多重化により、TCP接続ビルディングやTLSハンドシェイクなどのオーバーヘッドが大幅に減少し、リクエスト効率が向上します。
しかし、問題は、 curl_close()が呼び出されるたびに、現在のハンドルに対応する接続情報が破壊されることです。基礎となる接続が再利用値を使い果たしていない場合でも、それは切断されることを余儀なくされ、その結果、接続プールは無効でリソースの無駄になります。
function fetchData($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch); // 毎回接続を破壊します
return $response;
}
$data = fetchData("https://gitbox.net/api/data");
同時性が高いため、このパターンは毎回新しい接続を確立し、サーバー側に大きな圧力をかけ、ローカルリソースの消費を増加させます。
バッチリクエストでは、カールハンドルを再利用して、URLとリクエストパラメーターのみを更新できます。
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$urls = [
"https://gitbox.net/api/user",
"https://gitbox.net/api/data",
"https://gitbox.net/api/config"
];
foreach ($urls as $url) {
curl_setopt($ch, CURLOPT_URL, $url);
$response = curl_exec($ch);
// 対処する $response
}
curl_close($ch); // 最後に、統一された閉鎖
このアプローチは、接続の確立と閉鎖の頻度を大幅に削減し、同じライフサイクルで複数の同様のリクエストに適しています。
同時リクエストの場合、 curl_multi_init()を使用して複数のハンドルを管理し、実行後に均一に閉じることをお勧めします。
$multi = curl_multi_init();
$chs = [];
$urls = [
"https://gitbox.net/api/user",
"https://gitbox.net/api/data",
"https://gitbox.net/api/config"
];
foreach ($urls as $i => $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multi, $ch);
$chs[$i] = $ch;
}
$running = null;
do {
curl_multi_exec($multi, $running);
curl_multi_select($multi);
} while ($running > 0);
foreach ($chs as $ch) {
$content = curl_multi_getcontent($ch);
// 対処する $content
curl_multi_remove_handle($multi, $ch);
curl_close($ch);
}
curl_multi_close($multi);
この方法では、接続プールの多重化機能を完全に利用でき、高い同時インターフェイスリクエストシナリオで非常に実用的です。
HTTP Keep-Aliveプロトコルを使用してください。
頻繁に要求されるドメイン名の場合、DNSキャッシュまたはIP直接接続を考慮する必要があります。
curlopt_timeoutを合理的に使用して、死んだ接続を避けます。
PHP-FPM環境では、要求ごとにすべてのCurl構成の再構築を回避し、共通のロジックカプセル化を多重化します。
高い並行性PHPアプリケーションでは、 curl_close()は「クローズオフ」ツールではありません。その根本的な動作と接続の再利用メカニズムを理解することは、開発者がより効率的で安定したネットワーク通信ロジックを書き込むのに役立ちます。ハンドルを多重化するか、 curl_multiを使用することにより、リソースを節約するだけでなく、リクエストのパフォーマンスを大幅に改善できます。
接続ライフサイクルを合理的に管理することは、システムスループットを改善するための重要なステップです。この記事が実際のプロジェクトで最適化するように促すことを願っています。