$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上带有AT&amp; T的Win + XAMPP)上运行时,我的时间大约为60 毫秒。
但是,当上传到实时服务器并从那里运行时,运行时间会上升到20 秒范围。
如果我使用@dns_get_record($domain, DNS_MX)
,结果会相同。
可能导致这种情况的原因是什么?问题是AT&amp; 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
NB
AndreKR的回答让我用一个尾随时段来测试这些函数,并且仅将响应时间从几十秒减少到几毫秒。
这解决了问题,但它没有真正回答新问题:为什么?为了完整起见,我尽管添加 Nota Bene 并根据我的研究回答这个问题很重要。
我回到了源代码并阅读了大部分RFC-1034和RFC-1035。
事实证明,就DNS而言,完全合格域名(FQDN)实际上以句点结束。大多数对FQDN的引用都没有解释DNS具有绝对和相对域名的概念。 DNS告诉他们的方式恰恰是通过这个尾随时期。
如果DNS解析器看到DNS样式的FQDN(具有尾随句点),则它会熄灭并找到该DNS FQDN(绝对域名规范)的请求记录。这可能需要重试几次。例如,如果您要查找MX记录并且FQDN记录中不存在该记录,则可能存在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);
其中每一个都可能失败,整个过程需要永远。
事实证明,整个过程实际上都包含在A Security Problem and Proposed Correction With Widely Deployed DNS Software下的RFC中。值得一读。
答案 0 :(得分:10)
显然PHP DNS functions没有超时,dig
的默认超时为5 seconds(多次尝试)。
此外,您的开发和生产服务器可能使用不同的DNS服务器来解析名称。现在一些DNS服务器为无效域发送一个空答案,而有些(如djbdns) - 根本不发送任何答案(这与规范一致)。
另请注意,如果您不希望附加resolv.conf / Windows网络设置中的潜在搜索域,则应在域名中包含最终.
(点),这可能始终是可解析的如果他们有通配符。