11
$domain = 'abasdfasdfac.comlkjljkl';  // Yes, an ugly invalid domain

$start_time = microtime(true);
echo "<p>MX "; 
var_dump(checkdnsrr($domain, 'MX'));
echo "</p>";
$end_time = microtime(true);
echo "<p>run time: " . ($end_time - $start_time) . "</p>";

在我的开发系统(住宅 DSL 上的 Win+XAMPP w/AT&T)上运行它时,我的时间大约为 60毫秒。

但是,当上传到实时服务器并从那里运行时,运行时间会上升到 20范围内。

如果我改用,结果是一样的@dns_get_record($domain, DNS_MX)

这可能是什么原因造成的?AT&T 的 DNS 服务器返回结果是否比我的生产服务器指向的更快?不过,二十秒似乎过分了。

更重要的是,如何解决它?

我将其用作电子邮件验证的最后阶段。但是,我不能让用户在 DNS 查找返回时等待 20 秒。

编辑:

我对此进行了更深入的研究。dig在需要 20 到 30 秒对无效域进行 DNS 检查的同一台服务器上,从控制台使用速度很快。这可能是很重要的一点。checkdnsrr()使用或快速返回有效域@dns_get_record

作为一项临时措施,我正在考虑用我写的基于 - 的函数代替@dns_get_record我的电子邮件有效性检查:dig

// Use "dig" command to get DNS record data
// $type    ANY = Complete record
//          A   = Address Record
//          MX  = Mail Exchange Record
//          CNAME = Canonical Name Record  (http://en.wikipedia.org/wiki/Canonical_name_record)
//
//          more types: http://en.wikipedia.org/wiki/List_of_DNS_record_types
//
// $host    Domain to investigate
//
function dig_get_dns_record($type, $host) 
{ 
    $cleaned_host = escapeshellcmd($host);
    ob_start(); 
        // Note: for this to work on Windows/XAMPP "dig" has to be installed and the search path
        passthru("dig $type $cleaned_host"); 
        $lookup = ob_get_contents(); 
    ob_end_clean(); 
    //echo "<pre>" . $lookup . "</pre>";  // Remove comment to see dig output
    return $lookup; 
}   


// For the purposes of deciding if a domain is real, this checks, the MX, A and CNAME
// and returns FALSE if none are found.  If only one of the three exists we give it
// the benefit of the doubt.
//
// $host    Domain to investigate
//
function has_valid_dns($host)
{
    $result  = dig_get_dns_record("MX", $host);
    $result .= dig_get_dns_record("A", $host);
    $result .= dig_get_dns_record("CNAME", $host);
    return strpos($result, "ANSWER SECTION:") > 0;
}

虽然这会让我走出困境,但它真的不是一个答案。我确信真正的问题是 Linux 服务器上的配置设置。

如果您有兴趣测试延迟,这里有一个包含一些测试的页面(站点中的表单现在受到这种延迟的影响——请不要乱用表单,除非您真的只是想注册):

编辑:链接已删除,因为它不再相关并且页面将被删除

测试建议:

apple.com
apple.commmmmmmmmmm
example.com
asdfasdfasdf

注意

AndreKR 的回答让我用一个尾随时间来测试这些功能,仅此一项就将响应时间从几十秒减少到毫秒。

这解决了问题,但并没有真正回答新问题:为什么?为了完整起见,我认为添加此Nota Bene并根据我的研究回答该问题很重要。

我回到源头并阅读了大部分RFC-1034RFC-1035

事实证明,就 DNS 而言,完全限定域名 (FQDN) 实际上以句点结尾。大多数对 FQDN 的引用都没有解释 DNS 具有绝对相对域名的概念。DNS 区分它们的方式正是通过这个尾随句点。

如果 DNS 解析器看到 DNS 样式的 FQDN(带有尾随句点),它会出去并找到该 DNS FQDN(绝对域名规范)的请求记录。这可能需要重试几次。例如,如果您正在查找 FQDN 记录中不存在的 MX 记录,则可能存在 CNAME。DNS 解析器获取 CNAME 并启动新的 DNS 查询以尝试查找 MX 记录。

如果 DNS 解析器遇到相对域名规范会怎样?换句话说,任何没有尾随句点的东西。例如:“测试”。DNS 解析器实际上会尝试通过将一系列 DNS 后缀附加到提供的相对域名来将其转换为绝对 FQDN。例如:

@dns_get_record("abceabce.gov", DNS_MX);  // No trailing period === relative

例如,如果在主机上运行,www.example.com​​将至少生成以下一组查询:

@dns_get_record("abceabce.gov.www.example.com", DNS_MX);
@dns_get_record("abceabce.gov.example.com", DNS_MX);
@dns_get_record("abceabce.gov.com", DNS_MX);

这些中的每一个都可能失败,整个过程需要很长时间。

事实证明,整个过程实际上都包含在 RFC 中的A Security Problem and Proposed Correction With Widely Deployed DNS Software下。值得一读。

4

1 回答 1

15

显然PHP DNS 函数没有超时,而默认超时为dig5(多次尝试)。

此外,您的开发和生产服务器可能使用不同的 DNS 服务器来解析名称。现在一些 DNS 服务器为无效域发送一个空的答案,而一些 - 比如djbdns - 根本不发送任何答案(这很好,根据规范)。

另请注意,.如果您不希望附加来自 resolv.conf/Windows 网络设置的潜在搜索域,则应在域名中包含最后一个(点),如果它们具有通配符,则可能始终可以解析。

于 2012-12-29T01:25:27.247 回答