頻繁に初期化とCURLリソースのリリースは、特に多数の同時接続が含まれる場合、PHPで高い同時のHTTP要求を行うときにパフォーマンスの無駄を引き起こす可能性があります。この問題を解決するために、 CURL_SHARE_INIT関数は、DNSキャッシュ、Cookieなどの特定のリソースを共有する方法を提供し、それにより、マルチスレッドまたはマルチプロセス環境の実行効率を改善します。
この記事では、 curl_share_init関数を使用し、オブジェクト指向の方法でカプセル化する方法を紹介して、効率的な共有リソースプール管理メカニズムを実装します。
curl_share_init()は、共有ハンドルを初期化するためにlibcurlによって提供される関数です。複数のカールハンドルが次のリソースを共有できるようにします。
クッキーデータ
DNSキャッシュ
SSLセッション情報
接続プール
リソースを共有するための鍵は、 curl_setoptを使用して、各Curlハンドルの共有ハンドルを設定することです。
curl_setopt($ch, CURLOPT_SHARE, $shareHandle);
共有ハンドル自体は、 curl_share_init()によって作成され、 curl_share_setopt()を介して構成されています。
共有ハンドルの作成、管理、破壊をカプセル化し、マルチスレッド環境での再利用をサポートするシンプルな共有リソースプール管理クラスを設計できます。
class CurlSharePool
{
private static $instance = null;
private $shareHandle;
private function __construct()
{
$this->shareHandle = curl_share_init();
curl_share_setopt($this->shareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt($this->shareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
curl_share_setopt($this->shareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
}
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function getShareHandle()
{
return $this->shareHandle;
}
public function __destruct()
{
if ($this->shareHandle) {
curl_share_close($this->shareHandle);
}
}
}
共有リソースプールを使用して、複数のHTTPリクエストを送信する例を次に示します。
$urls = [
"https://m66.net/api/v1/data1",
"https://m66.net/api/v1/data2",
"https://m66.net/api/v1/data3"
];
$share = CurlSharePool::getInstance()->getShareHandle();
$multiHandle = curl_multi_init();
$curlHandles = [];
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SHARE, $share);
curl_multi_add_handle($multiHandle, $ch);
$curlHandles[] = $ch;
}
$running = null;
do {
curl_multi_exec($multiHandle, $running);
curl_multi_select($multiHandle);
} while ($running > 0);
foreach ($curlHandles as $ch) {
$response = curl_multi_getcontent($ch);
echo $response . PHP_EOL;
curl_multi_remove_handle($multiHandle, $ch);
curl_close($ch);
}
curl_multi_close($multiHandle);
共有ハンドルを使用する最大の利点は、DNSの再格付けとリクエストごとのSSL接続の再確立を避けることであり、これにより、高い並行性シナリオの効率を大幅に改善できることです。カプセル化クラスを使用すると、リソース管理を簡素化し、リソースの漏れを回避し、後のメンテナンスと拡張をより助長することができます。
curl_share_initはPHPでは一般的ではありませんが、高性能要件を持つシステムで低コストの最適化方法を提供します。共有ハンドルのオブジェクト管理モデルをカプセル化することにより、より効率的で安定したリソースの再利用を実現することができ、それにより、システム全体の応答速度と並行性機能が改善されます。
実際のアプリケーションでは、スレッドロックメカニズムを導入してスレッドの安全性を確保する、複数のリソースタイプのポリシー構成をサポートするなど、このタイプをさらに拡張できます。