当前位置: 首页> 最新文章列表> 如何通过使用 curl_share_init() 函数来避免 DNS 重复解析,提高性能?

如何通过使用 curl_share_init() 函数来避免 DNS 重复解析,提高性能?

M66 2025-06-23

在使用 PHP 的 cURL 扩展进行大量 HTTP 请求时,你可能遇到一个性能瓶颈:DNS 重复解析。每次请求时,cURL 都需要解析一次域名,这会带来额外的时间开销,尤其当你对同一个域名进行多次请求时。幸运的是,PHP 提供了一个叫 的函数,可以通过共享 DNS 缓存来避免这个问题。本文将带你了解如何使用它。

什么是 curl_share_init()?

curl_share_init() 是 cURL 扩展提供的一个函数,用于创建一个共享句柄(share handle)。这个共享句柄可以在多个 cURL 会话之间共享特定资源,比如 DNS 缓存、Cookie、SSL 会话等。
当我们启用共享 DNS 缓存时,多个请求只需要解析一次域名,后续请求可以直接复用结果,大大减少了网络延迟。

使用步骤

我们用一个简单的示例代码来讲解如何使用:

<?php
// 创建 cURL 共享句柄
$sh = curl_share_init();

// 设置共享选项,启用 DNS 共享
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);

$urls = [
    'https://m66.net/api/data1',
    'https://m66.net/api/data2',
    'https://m66.net/api/data3',
];

foreach ($urls as $url) {
    $ch = curl_init();

    // 设置 URL 和其他必要的选项
    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($ch) . PHP_EOL;
    } else {
        echo '响应: ' . $response . PHP_EOL;
    }

    // 关闭 cURL 会话
    curl_close($ch);
}

// 关闭共享句柄
curl_share_close($sh);
?>

代码讲解

1?? 创建共享句柄
我们用 curl_share_init() 创建一个共享句柄 $sh

2?? 设置共享资源
通过 curl_share_setopt(),我们指定共享 DNS 数据(CURL_LOCK_DATA_DNS)。

3?? 在每个 cURL 会话中绑定共享句柄
curl_setopt() 中,使用 CURLOPT_SHARE 将共享句柄关联到当前的 cURL 句柄 $ch

4?? 关闭句柄
完成所有请求后,记得用 curl_share_close() 释放共享句柄。

注意事项

  • 共享句柄必须在所有请求都完成后再关闭。

  • 如果程序中同时运行多线程或并发请求,需要小心锁定资源,防止竞争条件。

  • 共享 Cookie、SSL 等数据时也可以用同样的方式,只需替换 CURL_LOCK_DATA_* 常量。

性能提升有多大?

对于涉及大量相同域名请求的场景,比如 API 聚合、批量抓取、负载测试,避免 DNS 重复解析通常能带来 10%~30% 的性能提升,具体取决于 DNS 查询速度和服务器延迟。虽然不是每个场景都能有巨大改进,但这是一个简单、几乎无成本的优化手段。