什么会导致checkdnsrr()或dns_get_record()花费太长时间? [英] What would cause checkdnsrr() or dns_get_record() to take too long?

查看:1448
本文介绍了什么会导致checkdnsrr()或dns_get_record()花费太长时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

$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>";

当我运行这个时,我得到的顺序为60 毫秒我的开发系统(Win + XAMPP在住宅DSL w / AT& T)。

I am getting times in the order of 60 milliseconds when running this on my development system (Win+XAMPP on residential DSL w/AT&T).

然而,当上传到实时服务器并从那里运行时,运行时间上升到

However, when uploaded to the live server and run from there the run time goes up into the 20 second range.

如果我使用 @dns_get_record($ domain,DNS_MX)

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

What could be causing this? Is is a matter of AT&T's DNS servers returning with a result faster than whatever my production server is pointing to? Still, twenty seconds seems excessive.

更重要的是,如何修复?

More importantly, how does one fix it?

我正在使用这个作为电子邮件验证的最后阶段。但是,DNS查询返回时,我无法让用户等待二十秒。

I am using this as the last stage of email validation. However, I can't have the user waiting for twenty seconds while the DNS lookup returns.

编辑:

我已经进一步研究了一下。在同一台服务器上使用 dig ,需要20到30秒才能对无效域进行DNS检查。这可能是一个重要的一点。有效的域名可以快速返回,其中 checkdnsrr() @dns_get_record

I've looked into this a little further. Using dig from the console is fast on the same server that is taking 20 to 30 seconds to do a DNS check on invalid domains. That might be an important point. Valid domains return quickly with either checkdnsrr() or @dns_get_record.

作为一个临时措施,我正在寻找在我的电子邮件有效性检查中用 dig 替换 @dns_get_record 基本功能我写道:

As an interim measure I am looking into substituting @dns_get_record in my email validity check with a dig-based function I wrote:

// 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服务器上的一个配置设置。

While this will get me out of the woods it really isn't an answer. I am sure the real issue is a configuration setting on the Linux server.

如果你有兴趣测试延迟,这里有一个页面,几个测试该网站现在遭受这种延迟 - 请不要混淆表格,除非您实际上只想注册):

If you are interested in testing the delay, here's a page with a few tests (the forms in the site suffer from this delay right now --please don't mess with the forms unless you actually just want to sign-up):

编辑: / strong>链接被删除,因为它不再相关,页面将被删除

link removed as it is no longer relevant and page will be deleted

测试建议:

apple.com
apple.commmmmmmmmmm
example.com
asdfasdfasdf

NB

AndreKR的回答使我以一个拖尾的时期测试这些功能,并且单独减少了响应时间从几十秒到毫秒。

AndreKR's answer caused me to test these functions with a trailing period and that alone reduced the response time from tens of seconds to milliseconds.

这解决了问题,但它并没有真正回答新问题:为什么?为了完整,我虽然重要的是添加这个 Nota Bene ,并根据我的研究回答这个问题。

This solved the problem but it didn't really answer the new question: Why? For completeness I though it important to add this Nota Bene and answer that question based on my research.

我回到了源代码大部分 RFC-1034 RFC-1035

I went back to the source and read most of RFC-1034 and RFC-1035.

事实证明,就DNS而言,完全限定域名(FQDN)实际上是以期限结束。大多数对FQDN的引用并不能解释DNS具有绝对和相对域名的概念。 DNS告诉他们的方式正是通过这个拖尾期。

It turns out that, as far as DNS is concerned, a Fully Qualified Domain Name (FQDN) actually ends with a period. Most references to FQDN do not explain that DNS has the concept of an absolute and relative domain names. The way DNS tell them apart is precisely by means of this trailing period.

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

If a DNS resolver sees a DNS-style FQDN (with a trailing period) it goes out and finds the requested records for that DNS FQDN (an absolute domain name specification). This might require a few retries. For example, if you are looking for an MX record and that does not exist in the FQDN record, a CNAME might exist instead. The DNS resolver grabs the CNAME and initiates a new DNS inquiry to try to find the MX record.

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

What happens if the DNS resolver encounters a relative domain name specification? In other words, anything without a trailing period. For example: "testing". The DNS resolver will actually try to turn this into an absolute FQDN by appending a series of DNS suffixes to the provided relative domain name. For example:

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

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

If run on the host, say, www.example.com will generate at least the following set of queries:

@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);

这些都可能会失败,整个过程将永远存在。

Each of these is likely to fail and the whole process takes forever.

事实证明,在安全问题并建议使用广泛部署的DNS软件进行更正。值得一读。

It turns out that the whole process is actually covered in an RFC under A Security Problem and Proposed Correction With Widely Deployed DNS Software. It's worth reading.

推荐答案

显然, PHP DNS功能没有超时,而 dig 的默认超时是 5秒(有几次尝试)。

Apparently the PHP DNS functions don't have a timeout while the default timeout for dig is 5 seconds (with several tries).

此外,您的开发和生产服务器可能会使用不同的DNS服务器来解决名。现在一些DNS服务器为无效域发送空答案,有些则像 djbdns - 根本不发送任何答案

Furthermore your development and production server probably use different DNS servers for resolving names. Now some DNS servers send an empty answer for invalid domains and some - like djbdns - don't send any answer at all (which is fine with the specification).

另请注意,您应该包括最终的(点)如果您不希望附加resolv.conf / Windows网络设置中的潜在搜索域,那么该域名可能总是可解析的。

Also be aware that you should include the final . (dot) in the domain name if you don't want potential search domains from your resolv.conf/Windows network setup appended, which would be probably always resolvable if they have a wildcard.

这篇关于什么会导致checkdnsrr()或dns_get_record()花费太长时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆