PHP fsockopen()痛苦地缓慢

时间:2011-03-06 16:14:20

标签: php performance fsockopen

我正在使用fsockopen()来调用列表中的多个连接,以查看各种ip / host和端口的在线状态......

<?php
$socket = @fsockopen($row[2], $row[3], $errnum, $errstr, 1);
if ($errnum >= 1) { $status = 'offline'; } else { $status = 'online';}
fclose($socket);

如果有效,我不是在抱怨,但我有大约15个ip / ports我正在列表中检索(php for()命令..)。我想知道是否有更好的方法来做到这一点?这种方式非常慢!?!服务器大约需要1-2分钟才能回复所有人。

更新

<?php
$socket = @fsockopen("lounge.local", "80", $errnum, $errstr, 30);
if ($errnum >= 1) { $status = 'offline'; } else { $status = 'online'; }
?>

它将显示在列表中:“ReadyNAS AFP readynas.local:548 online”

我不知道还能告诉你什么?只需要永远加载结果集合......

7 个答案:

答案 0 :(得分:2)

如果您计划“ping”一些网址,我会建议您使用curl,为什么?你可以使用curl并行发送ping,看看这个 - &gt; http://www.php.net/manual/en/function.curl-multi-init.php。在以前的项目中,它应该向我们的服务器提供实时数据,我们曾经ping过主机以查看它们是否存活,而Curl是帮助我们的唯一选择。 它的建议可能不是解决问题的正确方法。

答案 1 :(得分:2)

根据我自己的经验:

此代码:

$sock=fsockopen('www.site.com', 80);
与以下相比,

速度较慢:

$sock=fsockopen(gethostbyname('www.site.com'), 80);

在PHP 5.4中测试。如果同时进行多个连接,可以保持主机解析结果并重新使用它,以进一步减少脚本时间执行,例如:

function myfunc_getIP($host) {
   if (isset($GLOBALS['my_cache'][$host])) {
      return $GLOBALS['my_cache'][$host];
   }

   return $GLOBALS['my_cache'][$host]=gethostbyname($host);
}

$sock=fsockopen(myfunc_getIP('www.site.com'), 80);

答案 2 :(得分:1)

您是否比较过fsockopen(servername)fsockopen(ip-address)的结果?如果timeout参数没有更改,则问题可能出在您的名称服务器中。如果具有IP地址的fsockopen更快,则必须修复名称服务器,或将域添加到/ etc / hosts文件。

答案 3 :(得分:0)

我建议这样做有点不同。 将此主机放在数据库中的表中,如:

++++++++++++++++++++++++++++++++++++
| host | port | status | timestamp |
++++++++++++++++++++++++++++++++++++

将状态检查部分移动到每5分钟运行一次的cron脚本或您想要的频率。 此脚本将检查主机:端口并更新每个记录的状态和时间戳,在您的页面中,您将只执行数据库查询并显示主机,其状态以及上次检查的时间(例如:1分钟前等等... ) 这样您的页面就会加载很快。

答案 4 :(得分:0)

根据php manual,有一个超时参数。尝试将其设置为较低的值。

编辑:要添加到Daniel的答案,nmap可能是最好的工具。使用cron作业进行设置,每隔X分钟扫描并更新一次记录。像

这样的东西
$ for ip in $(seq 6 8); 
do 
     port_open=$(nmap -oG - -p 80 10.1.0.$ip|grep open|wc -l); 
     echo "10.1.0.$ip:$port_open"; 
done

10.1.0.6:1
10.1.0.7:1
10.1.0.8:0

答案 5 :(得分:0)

fsockopen()的最后一个参数是超时,将其设置为较低的值以使脚本更快完成,如下所示:

fsockopen('192.168.1.93', 80, $errNo, $errStr, 0.01)

答案 6 :(得分:0)

我有一个问题,fsockopen请求很慢,但是wget非常活泼。在我的情况下,它发生了,因为主机名同时具有ipv4和ipv6地址,但ipv6已关闭。因此,每次请求ipv6超时需要20秒左右。