当前位置: 首页> 最新文章列表> 如何监控共享 DNS 是否生效

如何监控共享 DNS 是否生效

M66 2025-05-31

在使用 PHP 进行网络请求时,我们常用到 cURL 库。cURL 是一个强大的工具,它不仅支持简单的 HTTP 请求,还支持如 cookie、DNS、SSL 等高级特性。

其中,curl_share_init 是一个比较少为人知的 cURL 特性,它允许多个 cURL 句柄共享数据,比如 DNS 缓存、cookie、SSL session 等。通过共享 DNS 缓存,我们可以减少重复的域名解析,提高性能。

但在实际使用中,很多人会疑问:
共享的 DNS 缓存到底有没有生效?要如何监控?
本文就带你一步步分析,并给出完整的 PHP 示例。

什么是 curl_share_init

curl_share_init() 函数用于初始化一个共享句柄,配合 curl_setoptCURLOPT_SHARE 选项,可以让多个 cURL 请求共享某些数据。常见共享的内容包括:

  • DNS 缓存(CURL_LOCK_DATA_DNS

  • Cookie(CURL_LOCK_DATA_COOKIE

  • SSL 会话(CURL_LOCK_DATA_SSL_SESSION

例如:

$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);

这样多个 cURL 句柄绑定同一个 $sh,就能共享 DNS 缓存。

如何监控 DNS 是否被共享?

虽然 cURL 没有直接提供“监控 DNS 缓存命中”的接口,但我们可以间接观察:

  1. 首次请求耗时:首次请求通常包含 DNS 解析时间。

  2. 后续请求耗时:如果启用了共享 DNS,后续相同域名的请求应明显减少解析时间。

换句话说,我们可以用 CURLINFO_NAMELOOKUP_TIMECURLINFO_TOTAL_TIME 两个 cURL 选项,分别监控:

  • 域名解析时间

  • 总耗时

通过比较首个请求与后续请求的 NAMELOOKUP_TIME,就能判断 DNS 缓存是否生效。

完整示例代码

以下是一个使用 curl_share_init 的完整 PHP 代码,向 https://m66.net/test 发送两次请求,并打印 DNS 解析时间:

<?php
$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);

$url = 'https://m66.net/test';

// 第一次请求
$ch1 = curl_init($url);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_SHARE, $sh);

curl_exec($ch1);
$dns_time1 = curl_getinfo($ch1, CURLINFO_NAMELOOKUP_TIME);
$total_time1 = curl_getinfo($ch1, CURLINFO_TOTAL_TIME);
curl_close($ch1);

echo "第一次请求:\n";
echo "DNS 解析时间: {$dns_time1} 秒\n";
echo "总耗时: {$total_time1} 秒\n";

// 等待1秒,模拟新的请求
sleep(1);

// 第二次请求
$ch2 = curl_init($url);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_SHARE, $sh);

curl_exec($ch2);
$dns_time2 = curl_getinfo($ch2, CURLINFO_NAMELOOKUP_TIME);
$total_time2 = curl_getinfo($ch2, CURLINFO_TOTAL_TIME);
curl_close($ch2);

echo "\n第二次请求:\n";
echo "DNS 解析时间: {$dns_time2} 秒\n";
echo "总耗时: {$total_time2} 秒\n";

// 清理
curl_share_close($sh);
?>

代码要点解析

? 启用共享:用 curl_share_initCURLSHOPT_SHARE 配置共享 DNS 数据。

? 获取时间:通过 curl_getinfo 拿到 CURLINFO_NAMELOOKUP_TIME

? 对比效果:第一次请求通常会有明显的 DNS 耗时(比如几十毫秒);第二次如果缓存生效,NAMELOOKUP_TIME 会接近 0。

注意事项

  • 同一域名:只有相同的主机名(例如 m66.net)才能命中缓存。

  • PHP cURL 版本:部分老版本 PHP 可能不完全支持 curl_share。建议用 phpinfo() 检查 cURL 版本。

  • 线程安全:如果在多线程或多进程环境下使用 curl_share,需要确保加锁安全。