高い同時ネットワークリクエストにPHPを使用する場合、HTTPSハンドシェイクのオーバーヘッドは、多くの場合、パフォーマンスボトルネックの1つです。各HTTPSリクエストには、完全なTLSハンドシェイクプロセスが必要です。これは、短期間で複数のリクエストが開始されると、全体的な応答速度に大きく影響します。幸いなことに、Curlはcurl_share_init関数を提供します。これは、ハンドルを共有することで複数のリクエスト間でマルチプレックス接続データを使用して、HTTPSハンドシェイクの頻度を減らし、効率を改善できます。
curl_share_initは、共有ハンドルの初期化に使用されるCurl拡張機能の関数です。この共有ハンドルを通じて、異なるカールセッションはDNSキャッシュ、SSLセッション、Cookieなどの情報を共有できます。これは、複数のリクエストが同じドメイン名を指し、共有SSLセッションが有効になっている場合、リクエストは以前のHTTPSハンドシェイクを再利用でき、レイテンシーとCPUの消費を大幅に減らすことができることを意味します。
curl_share_initを使用してHTTPSセッションを共有する実用的なコードを次に示します。
<?php
// 共有ハンドルを初期化します
$sh = curl_share_init();
// 共有オプションを設定します,開ける SSL セッション共有
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
// 複数のリクエストを準備します
$urls = [
'https://m66.net/api/endpoint1',
'https://m66.net/api/endpoint2',
'https://m66.net/api/endpoint3',
];
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SHARE, $sh); // アプリ共有ハンドル
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Curl error: ' . curl_error($ch) . "\n";
} else {
echo "Response from {$url}:\n$response\n\n";
}
curl_close($ch);
}
// 共有ハンドルをクリーンアップします
curl_share_close($sh);
?>
この例では、3つの要求すべてがM66.NETドメイン名の下の異なるインターフェイスを指し、すべて同じ共有ハンドルを介してSSLセッションを共有します。これは、最初のリクエストのHTTPSハンドシェイクを完了した後、その後のリクエストが既存のセッションを再利用して、繰り返しの握手プロセスを回避できることを意味します。
スレッドの安全性:PHP自体はシングルスレッドですが、マルチスレッド環境で共有ハンドルを使用する場合は、スレッドの同期の問題に注意する必要があります。
curlshopt_unshareを使用します。特定のタイプのデータ(CookieやDNSキャッシュなど)を特定の段階で解散する必要がある場合は、 curlshopt_unshareを使用できます。
同じホストの再利用のみが効果的です。共有SSLセッションは、同じホスト(ホスト)とポートの間でのみ有効になり、ドメイン名で共有できません。
CURL_SHARE_INITと共有ハンドル構成を合理的に使用することにより、多数のHTTPSリクエストを作成する際にTLSハンドシェイクのシステムオーバーヘッドを効果的に減らすことができます。これは、マイクロサービス通信、高周波API要求、データクロール、その他のシナリオに大きな利点があります。パフォーマンスを向上させるだけでなく、サーバーとクライアントのリソース消費も削減するだけでなく、PHP高性能ネットワークプログラミングの重要なスキルです。