php中gethostbyaddr()函数的超时问题
最近我注意到,在我的新服务器上,我的站点上使用了php中gethostbyaddr()函数的超时问题,php,Php,最近我注意到,在我的新服务器上,我的站点上使用了gethostbyaddr()函数来获取referes的主机,它使页面加载速度慢了5倍 当我移除它时,超时问题就消失了 此函数和我的新Centos linux服务器配置有什么问题 还有什么可以代替这个php函数来获取我的推荐人的主机名。这可能是DNS解析的暂时缓慢,以后可能会自行清除。除了从PHP中进行如下系统调用之外,实在没有任何方法可以替代gethostbyaddr()。(gethostbyaddr()基本上就是这样做的) 您可以使用以下命令行
gethostbyaddr()
函数来获取referes的主机,它使页面加载速度慢了5倍
当我移除它时,超时问题就消失了
此函数和我的新Centos linux服务器配置有什么问题
还有什么可以代替这个php函数来获取我的推荐人的主机名。这可能是DNS解析的暂时缓慢,以后可能会自行清除。除了从PHP中进行如下系统调用之外,实在没有任何方法可以替代
gethostbyaddr()
。(gethostbyaddr()
基本上就是这样做的)
您可以使用以下命令行测试分辨率是否较慢:
# choose an IP address you know the resolution of...
$ host 123.123.123.123
如果这不能很快返回,您可能会遇到DNS问题
检查
/etc/resolv.conf
的内容,如果您有备用DNS服务器,您可以将其指向该服务器,试试该服务器。您有什么类型的web主机?共享、VPS或专用gethostbyaddr()
性能取决于web服务器DNS解析的有效性。有些情况可能会降低其性能,但您仍然需要至少说明您使用的主机类型。我认为您应该为gethostbyaddr()结果实现某种类型的缓存系统(嗯,大多数DNS服务器都有内置的缓存系统,但您的主机可能会因某些原因出现故障)或者尝试使用其他DNS服务器(使用系统调用或更好的PHP套接字)。我为gethostbyaddr()编写了这个有用的替代品:
诀窍是使用主机功能,但您必须检查$ip是否是真正的ip,以避免攻击。
我把计时器设为1秒
它比使用gethostbyaddr快得多,尽管在循环中使用时速度仍然很慢。不幸的是,某些isp不维护某些ip地址的反向dns记录,因此dns查找总是会失败。问题是要等多久才能放弃 一些主机服务将gethostbyaddr函数超时设置为实短,如果查找不成功,则ip地址将替换为主机名。这会加快速度,防止在显示调用此函数的页面时出现长时间延迟
您应该始终仔细检查不显示主机名的日志条目,因为它们经常表明访问者来自一个ip地址,该ip地址具有恶意互联网活动的声誉。从XP升级到7后,它影响了PHP对IPv4和IPv6的处理(例如,127.0.0.1返回为::1)我已经修改了一些代码来暂时解决这个问题。原来我在IPv6补丁上使用了
gethostbyaddr
,因此它在PHP上的计时被卡住了
以前
$ip = ip2long6($ip);
$host = gethostbyaddr($ip);
在
$host = gethostbyaddr($_SERVER['REMOTE_ADDR']);
您可以使用Xdebug和WinCacheGrind(我使用XAMPP进行本地测试)来查找超时的原因,下面是一个视频教程,可以快速浏览
希望这能让某人保持理智。:-) As不支持超时,我的主机设置不允许shell命令。我决定使用本地API:
<?php
$ip = isset($_GET['ip']) ? filter_var($_GET['ip'], FILTER_VALIDATE_IP) : false;
if ($ip) {
echo json_encode(gethostbyaddr($ip));
}
?>
正如你所看到的,我设置了超时
样本输出:
IP: 56.152.200.204
HOST: Timeout!
Execution Time: 801 ms
IP: 81.139.131.130
HOST: host81-139-131-130.range81-139.btcentralplus.com
Execution Time: 52 ms
我不知道为什么,但在我的设置中,0.4
超时在>800毫秒后开始,因此我需要将该值加倍以获得最终超时。也许其他人可以对此发表评论
警告这将在服务器上为主脚本上的每个请求创建一个额外的http请求 +1用于提及(即,告诉我)主机命令。@Pete主机的
-x
标志不正确。我把它与dig-x
混淆了。仅使用host
而不使用任何标志将返回IP的主机名。请提供有用的解决方案,而不要因为人们缺乏理解而责备他们。请使用“host-W 1”命令。我曾经遇到过这样的情况,它经常挂起,即使它不应该使用-w1选项。解决方案很简单:在命令前面加上“timeout”命令,并在那里指定超时。
<?php
$ip = isset($_GET['ip']) ? filter_var($_GET['ip'], FILTER_VALIDATE_IP) : false;
if ($ip) {
echo json_encode(gethostbyaddr($ip));
}
?>
<?php
// prepare host url
function isSecure() {
return ((isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443) ? 's' : '';
}
$protocol_host = 'http' . isSecure() . '://' . filter_input(INPUT_SERVER, 'HTTP_HOST', FILTER_SANITIZE_URL);
// dns request
$context = stream_context_create(array(
'http' => array(
'timeout' => 0.4,// 400 ms
)
));
$ip = long2ip(mt_rand(0, "4294967295"));
// note: the host url needs public access!
$host = json_decode(@file_get_contents($protocol_host . '/hostAPI.php?ip=' . $ip, false, $context), true);
// output
echo 'IP: ' . $ip . "<br>\n";
echo 'HOST: ' . ($host ? $host : 'Timeout!') . "<br>\n";
echo 'Execution Time: ' . round((microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]) * 1000) . ' ms';
?>
IP: 56.152.200.204
HOST: Timeout!
Execution Time: 801 ms
IP: 81.139.131.130
HOST: host81-139-131-130.range81-139.btcentralplus.com
Execution Time: 52 ms